]> err.no Git - util-linux/commitdiff
Imported from util-linux-2.9i tarball.
authorKarel Zak <kzak@redhat.com>
Wed, 6 Dec 2006 23:25:37 +0000 (00:25 +0100)
committerKarel Zak <kzak@redhat.com>
Wed, 6 Dec 2006 23:25:37 +0000 (00:25 +0100)
162 files changed:
ANNOUNCE
HISTORY [moved from README with 86% similarity]
INSTALL [new file with mode: 0644]
LSM
MAINTAINERS
MCONFIG
Makefile
attic/pidof.c [new file with mode: 0644]
attic/strings.1 [moved from text-utils/strings.1 with 100% similarity]
attic/strings.c [moved from text-utils/strings.c with 100% similarity]
bsd/Makefile [deleted file]
bsd/getopt.3 [deleted file]
bsd/getopt.c [deleted file]
disk-utils/Makefile
disk-utils/cfdisk.8.bak [deleted file]
disk-utils/cfdisk.c.bak [deleted file]
disk-utils/cfdisk.c.orig [deleted file]
disk-utils/fdformat.c
disk-utils/fdprm
disk-utils/frag.8 [deleted file]
disk-utils/frag.c [deleted file]
disk-utils/fsck.minix.c
disk-utils/mkfs.8
disk-utils/mkfs.minix.c
disk-utils/mkswap.8
disk-utils/mkswap.c
disk-utils/setfdprm.c
example.files/filesystems [new file with mode: 0644]
example.files/issue0 [new file with mode: 0644]
example.files/syslog.conf [deleted file]
example.files/syslog.conf.alt [deleted file]
fdisk/Makefile [new file with mode: 0644]
fdisk/README.cfdisk [moved from disk-utils/README.cfdisk with 100% similarity]
fdisk/README.fdisk [moved from disk-utils/README.fdisk with 99% similarity]
fdisk/cfdisk.8 [moved from disk-utils/cfdisk.8 with 98% similarity]
fdisk/cfdisk.c [moved from disk-utils/cfdisk.c with 92% similarity]
fdisk/fdisk.8 [moved from disk-utils/fdisk.8 with 89% similarity]
fdisk/fdisk.c [moved from disk-utils/fdisk.c with 78% similarity]
fdisk/fdisk.h [moved from disk-utils/fdisk.h with 73% similarity]
fdisk/fdiskaixlabel.c [new file with mode: 0644]
fdisk/fdiskaixlabel.h [new file with mode: 0644]
fdisk/fdiskbsdlabel.c [moved from disk-utils/fdisklabel.c with 96% similarity]
fdisk/fdiskbsdlabel.h [moved from disk-utils/fdisklabel.h with 99% similarity]
fdisk/fdisksgilabel.c [new file with mode: 0644]
fdisk/fdisksgilabel.h [new file with mode: 0644]
fdisk/fdisksunlabel.c [moved from disk-utils/fdisksunlabel.c with 73% similarity]
fdisk/fdisksunlabel.h [moved from disk-utils/fdisksunlabel.h with 97% similarity]
fdisk/llseek.c [moved from disk-utils/llseek.c with 100% similarity]
fdisk/sfdisk.8 [moved from disk-utils/sfdisk.8 with 97% similarity]
fdisk/sfdisk.c [moved from disk-utils/sfdisk.c with 98% similarity]
fdisk/sfdisk.examples [moved from disk-utils/sfdisk.examples with 100% similarity]
games/Makefile
getopt-1.0.3a/COPYING [moved from getopt/COPYING with 100% similarity]
getopt-1.0.3a/Changelog [moved from getopt/Changelog with 53% similarity]
getopt-1.0.3a/Makefile [new file with mode: 0644]
getopt-1.0.3a/README [moved from getopt/README with 93% similarity]
getopt-1.0.3a/TODO [moved from getopt/TODO with 83% similarity]
getopt-1.0.3a/getopt.1 [moved from getopt/getopt.1 with 100% similarity]
getopt-1.0.3a/getopt.c [moved from getopt/getopt.c with 99% similarity]
getopt-1.0.3a/gnu/getopt.c [moved from getopt/gnu/getopt.c with 100% similarity]
getopt-1.0.3a/gnu/getopt.h [moved from getopt/gnu/getopt.h with 100% similarity]
getopt-1.0.3a/gnu/getopt1.c [moved from getopt/gnu/getopt1.c with 100% similarity]
getopt-1.0.3a/parse.bash [moved from getopt/parse.bash with 100% similarity]
getopt-1.0.3a/parse.tcsh [moved from getopt/parse.tcsh with 83% similarity]
getopt-1.0.3a/test.bash [moved from getopt/test.bash with 100% similarity]
getopt-1.0.3a/test.tcsh [moved from getopt/test.tcsh with 100% similarity]
getopt/Makefile [deleted file]
lib/Makefile [new file with mode: 0644]
lib/err.c [moved from bsd/err.c with 100% similarity]
lib/err.h [moved from bsd/err.h with 100% similarity]
lib/linux_reboot.h [new file with mode: 0644]
lib/my_reboot.c [new file with mode: 0644]
lib/pathnames.h [moved from bsd/pathnames.h with 95% similarity]
lib/setproctitle.c [new file with mode: 0644]
lib/setproctitle.h [new file with mode: 0644]
login-utils/Makefile
login-utils/agetty.c
login-utils/checktty.c
login-utils/chfn.c
login-utils/chsh.1
login-utils/chsh.c
login-utils/last.1.orig [deleted file]
login-utils/last.c
login-utils/last.c.orig [deleted file]
login-utils/login.1
login-utils/login.c
login-utils/passwd.1
login-utils/passwd.c
login-utils/shutdown.8
login-utils/shutdown.c
login-utils/simpleinit.c
login-utils/vipw.c
misc-utils/Makefile
misc-utils/cal.1
misc-utils/cal.c
misc-utils/chkdupexe.pl [changed mode: 0644->0755]
misc-utils/ddate.1
misc-utils/ddate.c
misc-utils/hostname.c.orig [deleted file]
misc-utils/kill.c
misc-utils/look.c
misc-utils/mcookie.1
misc-utils/mcookie.c
misc-utils/procs.c
misc-utils/script.c
misc-utils/setterm.c
misc-utils/whereis.c
misc-utils/write.c
mkminix-0.1/README [new file with mode: 0644]
mkminix-0.1/linux/minix_fs.h [new file with mode: 0644]
mkminix-0.1/mkmin-dj.h [new file with mode: 0644]
mkminix-0.1/mkminix.diff [new file with mode: 0644]
mount/Makefile
mount/Makefile.standalone
mount/fstab.5
mount/fstab.c
mount/fstab.h
mount/getusername.c [new file with mode: 0644]
mount/getusername.h [new file with mode: 0644]
mount/linux_fs.h
mount/losetup.c
mount/mk_loop_h
mount/mntent.c [new file with mode: 0644]
mount/mntent.h [new file with mode: 0644]
mount/mount.8
mount/mount.c
mount/mount_by_label.c [new file with mode: 0644]
mount/mount_by_label.h [new file with mode: 0644]
mount/mount_constants.h
mount/mount_guess_fstype.c [new file with mode: 0644]
mount/mount_guess_fstype.h [new file with mode: 0644]
mount/nfsmount.c
mount/nfsmount_xdr.c
mount/sundries.c
mount/swap.configure
mount/swap_constants.h [new file with mode: 0644]
mount/swapon.8
mount/swapon.c
mount/umount.c
mount/version.c
sys-utils/Makefile
sys-utils/ctrlaltdel.c
sys-utils/hwclock.8
sys-utils/hwclock.c
sys-utils/ipcrm.c
sys-utils/ipcs.c
sys-utils/kbdrate.8
sys-utils/kbdrate.c
sys-utils/lpcntl.8 [deleted file]
sys-utils/lpcntl.c [deleted file]
sys-utils/sln.8 [moved from sys-utils/sln.1 with 64% similarity]
text-utils/Makefile
text-utils/colcrt.c
text-utils/colrm.c
text-utils/column.c
text-utils/more.c
text-utils/ul.c
uio.h-diff [deleted file]
util-linux-2.1.Announce [deleted file]
util-linux-2.1.bin.Notes [deleted file]
util-linux-2.1.lsm [deleted file]
version.h

index 0d762863c4fc073b9a8bf4b95f86ae45633825c3..1eed25ef11d19d59d36d5ada4e1746a017287bb4 100644 (file)
--- a/ANNOUNCE
+++ b/ANNOUNCE
@@ -1,14 +1,14 @@
-util-linux-2.8.tar.gz (source only distribution)
+util-linux-2.9.tar.gz (source only distribution)
 
 READ the README file and the stuff below.
 
-util-linux-2.8.tar.gz (source only distribution)
+util-linux-2.9.tar.gz (source only distribution)
 
 NOTE: Before installing util-linux. READ the README or risk nuking
 your system.  Thank you.
 
     Util-linux is a suite of essential utilities for any Linux system.
-It's primary audience is system integrators (like the people at Debian
+Its primary audience is system integrators (like the people at Debian
 and RedHat) and DIY Linux hackers. The rest of you will get a digested
 version of util-linux installed with no risk to your sanity.
 
@@ -20,12 +20,13 @@ and Linux 2.0/Libc 5 and has also been tested with libc 6 on intel,
 alpha and sparc.  People are encouraged to make _nice_ patches to
 util-linux and submitting them to util-linux@math.uio.no.  Thank you.
 
-Util-Linux 2.8 is imediately available from
-  ftp.math.uio.no:/pub/linux, and
-  sunsite.uio.no:/pub/unix/linux/packages/util-linux,
-and will appear at
-  sunsite.unc.edu:/pub/Linux/system/Misc, as well as
+Util-Linux 2.9 is imediately available from
+  ftp.win.tue.nl:/pub/linux/util
+and will probably appear soon at
+  ftp.math.uio.no:/pub/linux
+  sunsite.uio.no:/pub/unix/linux/packages/util-linux
+  sunsite.unc.edu:/pub/Linux/system/Misc
   tsx-11.mit.edu:/pub/linux/packages/utils 
-when the people in charge there get time.
 
-Nicolai Langfeldt
+Andries Brouwer
+
diff --git a/README b/HISTORY
similarity index 86%
rename from README
rename to HISTORY
index cf30bf0ae30639186c3edbc1f9b6533efb279b6f..f0ccc9ab5f8ecc31228b68827733fe6e1d35efe1 100644 (file)
--- a/README
+++ b/HISTORY
-util-linux 2.8:
+util-linux 2.9i:
+
+* fixed 2.9h typo in more
+* added -m: `Monday is 1st day' option to cal (Jean-Francois Bignolles)
+* changed PAM stuff in login.c (+- mjohnson)
+* added warning to cfdisk in case of multiple bootable partitions
+* added 2048-byte sector support in fdisk (Oliver Schaertel)
+
+util-linux 2.9h:
+
+* mount recognizes "uid=useruid" and "gid=usergid" in /etc/fstab.
+* documented the fact that "mount -t smb" will call /sbin/mount.smb.
+* mount gives clear error message when fstab does not end in newline.
+* swapon checks mode of file
+* cfdisk got a more specific exit status (Enrique Zanardi)
+
+util-linux 2.9g:
+
+* mount updates (locking, "users" keyword, "/etc/filesystems",
+  "proto" and "vers" options in nfsmount, ...)
+
+util-linux 2.9f:
+
+* made ul handle lines of arbitrary length (Scott Maxwell)
+* killed some C/H/S nonsense in fdisk
+* fixes for archs with unsigned char type (Ambrose Li)
+* fdisk fixes for power pc (Tom Rini)
+* added a define for NCURSES_CONST
+* fixes for list of signals in kill.c
+* fixes for user name length in last.c
+
+util-linux 2.9e:
+
+* added a forgotten declaration to login.c (Christian Oyarzun)
 
-WARNING: THE PROGRAMS IN THIS SUITE DO *NOT* SUPPORT SHADOW PASSWORD FILES!
-        UNLESS YOU USE PAM.
+util-linux 2.9d:
 
-WARNING: THIS COLLECTION CONFLICTS WITH SYSTEM V INITTAB.
-         UNLESS YOU CONFIGURE IT NOT TO.
+* fixed segfault in umount caused by Wilcox' patch (Steffen Zahn)
+* added lnz stuff to fdisk
 
-WARNING: USE GNU TAR -- OTHER TARS WILL FAIL SILENTLY!
+util-linux 2.9c:
 
-WARNING: DO *NOT* INSTALL WITHOUT THINKING.
+* refixed PAM stuff in login.c that was broken in 2.8.
 
-WARNING: The simpleinit and some other programs in this package are
-        *NOT* System V compliant.  These utilities are meant to be
-        used by people who build their own systems.  If you are not
-         a wizard, do *NOT* blindly install these utilities: they could
-         prevent you from logging into your system.  Have a boot floppy
-         ready, especially if you don't know what you are doing.  It's a
-        great way to learn though ;-)
+util-linux 2.9b:
 
+* split README into INSTALL and HISTORY
+* added a sentence to swapon.8
+* behaviour of write on non-ASCII fixed
+* hwclock adapted to survive a failing mktime()
 
-To install from source:
+util-linux 2.9a:
 
-1) Get source distribution (see the .lsm file for locations)
-2) Untar util-linux-2.8.tar.gz in /usr/src
-3) cd util-linux-2.8
-4) Edit MCONFIG
-5) make
-6) make install
-7) If you want to use simpleinit and agetty, then make softlinks from
-   /sbin/init to simpleinit and from /sbin/getty to agetty, but make sure
-   that your /etc/inittab is set up right (this is *NOT* the System V
-   compatible init!), or you will be hosed.  If you are using the SysV
-   init and/or some other getty, they you can keep using those.
+* added an include to lib/my_reboot.c so that __GLIBC__ is defined
+* added setlocale() to login-utils/chfn.c
+* do not recompute MAIL in login-utils/login.c
+
+util-linux 2.9:
+
+HIGHLIGHTS for version 2.9:
+
+1) Removed programs:
+   - strings. There is a version in binutils.
+   - frag. (Moved to historic in 2.4, crept back in 2.5. Gone again.)
+1a) Not yet removed program:
+   - setfdprm. It also is in fdutils-5.2 (with an exceptionally
+     ugly man page).
+1b) Removed directory:
+   - bsd. (The routine getopt() is in libc. err() moved to lib.)
+2) Improvements:
+   - ddate has been fixed to count down to the new, right X-day
+   - look is now willing to search non-English dictionaries
+     (i.e., uses locale)
+   - cal now knows that Dutch day abbreviations have length 2 only
+   - mcookie does not block when no random stuff is available
+   - shutdown got a configuration file /etc/shutdown.conf
+   - fdisk now reads SGI disk labels (thanks to Andreas Neuper)
+   - mkswap now knows about new swap areas; mkswap.8 has been rewritten
+   - umount knows about umount2() and forced unmounting of nfs mounts
+     (however, I don't think it really works)
+   - mount is now willing to handle file names with embedded spaces
+   - mount can now mount things by UUID or volume name
+3) Uglifications:
+   - swap.h has been replaced by a private swap_constants.h since
+     <linux/swap.h> does not compile
+   - reboot has become a private routine, since libc5 and glibc2 conflict
+   - a mkminix-0.1 directory contains some patches to let mkfs.minix
+     work under DOS. (Untested.)
+4) Numerous other small changes.
+
+0xF) Send questions and/or patches to util-linux@math.uio.no
+
+util-linux 2.8:
 
 HIGHLIGHTS for version 2.8:
 
-0a) It's been way to long since the last release.  My fault.
-0b) NO PAM patches.
 1) New programs:
    - getopt(1) by Frodo Looijaard replaces the older bsd based version.
      Keywords: Backward compatible, supports --long options.
 1) Removed programs: 
    - chroot: is no longer in util-linux.  Get it free with GNU sh-utils
-   - frag: 
-   - lpcntl: This was removed in an earlier release (2.7) but I forgot to
-       mention it.
    - hostid: No-one could figure out the right way for this program to
                work.  Another hostid program is included in poeigl
                (see the LSM, Primary-site: ftp.daimi.aau.dk /pub/linux/poe)
@@ -54,7 +108,6 @@ HIGHLIGHTS for version 2.8:
    are encouraged to send patches.
 3) rev now only limits linelength to memory capacity
 4) dmesg now uses a buffer that matches the kernel buffer in size (8KB)
-0xF) Send questions and/or patches to util-linux@math.uio.no
 
 
 util-linux 2.7:
@@ -65,12 +118,13 @@ HIGLIGHTS for version 2.7:
    converted to use terminfo (instead of termcap).
 
 2) Removed progams:
-   - clock: Dropped entierly.  Use hwclock (included).
+   - clock: Dropped entirely.  Use hwclock (included).
    - sync: is in gnu fileutils.
    - setserial: Is being maintained by Ted Ts'o, he recommends
        setserial-2.12 (2.13 is bad luck)
    - clear: Included in ncurses
    - hostname, domainname, dnsdomainname: It's in net-utils.
+   - lpcntl.
 
 3) Bugfixes, additions:
    - cfdisk: A much improved version. All known bugs have been fixed.
@@ -86,11 +140,11 @@ HIGLIGHTS for version 2.7:
      ways to deal with this:
      - Don't run rpcgen, the needed pre-generated sources are included
        (nfsmount_xdr.c).  You must hack mount/Makefile to do this.
-     - Edit the source emited by rpcgen so it can compile.  This is very
+     - Edit the source emitted by rpcgen so it can compile.  This is very
        simple if you know C.
      - Disable the NFS parts of mount.  You have to edit mount/Makefile
        to do this.
-     - Use some other rpcgen
+     - Use some other rpcgen.
 
 util-linux 2.6.1
 
@@ -125,7 +179,7 @@ HIGHLIGHTS for version 2.6:
    UPDATES TO: util-linux@math.uio.no.
 
 1) Removed programs:
-   - md5sum: available in GNU textutils.
+   - md5sum, dsplit: available in GNU textutils.
    - syslogd: Sysklogd is now prefered.  It is available at 
        tsx-11.mit.edu:/pub/sources/sbin
        sunsite.unc.edu:/pub/Linux/system/Daemons
@@ -338,7 +392,7 @@ login-utils:
     vipw: 5.16 (Berkeley) 3/3/91, with modifications by Mike Grupenhoff
           <kashmir@umiacs.UMD.EDU> 
     wall: 8.2 (Berkeley) 11/16/93 (With changes so that damaging escape
-          sequences cannot be sent. 
+          sequences cannot be sent.)
           ftp.cdrom.com:/pub/bsd-sources/4.4BSD-Lite/usr/src/usr.bin
 
 
@@ -357,6 +411,8 @@ misc-utils:
             gatekeeper.dec.com:/pub/usenet/comp.sources.misc/volume40/dsplit
     getopt (getoptprog): jhunix.hcf.jhu.edu:
            /pub/public_domain_software/NetBSD/usr/src/usr.bin/getopt
+          replaced by getopt-1.0.3.tar.gz from Frodo Looijaard,
+          found at http://huizen.dds.nl/~frodol
     hostid: Mitch DSouza (m.dsouza@mrc-apu.cam.ac.uk)
             ftp.daimi.aau.dk:/pub/linux/poe/poeigl-1.37.tar.gz
     hostname/dnsdomainname: Peter Tobias <tobias@server.et-inf.fho-emden.de>
@@ -455,7 +511,7 @@ sys-utils:
     rdev: almesber@nessie.cs.id.ethz.ch (Werner Almesberger), with
           modifications from Peter MacDonald, Stephen Tweedie
           (sct@dcs.ed.ac.uk), and Dave (gentzel@nova.enet.dec.com)
-    readprofile: Alessandro Rubini
+    readprofile: Alessandro Rubini from readprofile-2.0.tar.gz
     renice: 8.1 (Berkeley) 6/9/93
             ftp.cdrom.com:/pub/bsd-sources/4.4BSD-Lite/usr/src/usr.bin
     setserial: Michael K. Johnson (johnsonm@stolaf.edu) re-released Rick
diff --git a/INSTALL b/INSTALL
new file mode 100644 (file)
index 0000000..c6a463e
--- /dev/null
+++ b/INSTALL
@@ -0,0 +1,57 @@
+
+WARNING: THE PROGRAMS IN THIS SUITE DO *NOT* SUPPORT SHADOW PASSWORD FILES!
+        UNLESS YOU USE PAM.
+
+WARNING: THIS COLLECTION CONFLICTS WITH SYSTEM V INITTAB.
+         UNLESS YOU CONFIGURE IT NOT TO.
+
+WARNING: USE GNU TAR -- OTHER TARS WILL FAIL SILENTLY!
+
+WARNING: DO *NOT* INSTALL WITHOUT THINKING.
+
+WARNING: The simpleinit and some other programs in this package are
+        *NOT* System V compliant.  These utilities are meant to be
+        used by people who build their own systems.  If you are not
+         a wizard, do *NOT* blindly install these utilities: they could
+         prevent you from logging into your system.  Have a boot floppy
+         ready, especially if you don't know what you are doing.  It's a
+        great way to learn though ;-)
+
+
+To install from source:
+
+1) Get source distribution (see the .lsm file for locations)
+2) Untar util-linux-2.9.tar.gz somewhere
+3) cd util-linux-2.9
+4) Edit MCONFIG
+5) make
+6) make install
+7) If you want to use simpleinit and agetty, then make softlinks from
+   /sbin/init to simpleinit and from /sbin/getty to agetty, but make sure
+   that your /etc/inittab is set up right (this is *NOT* the System V
+   compatible init!), or you will be hosed.  If you are using the SysV
+   init and/or some other getty, they you can keep using those.
+
+
+If you have compilation problems:
+
+- with -lcrypt: you forgot to edit MCONFIG and write HAVE_LIBCRYPT=no.
+- in cfdisk or setterm: you forgot to edit MCONFIG and write HAVE_NCURSES=no
+  (or you forgot to write CURSESFLAGS=-I/usr/include/ncurses -DNCH=0)?
+- in fdisksunlabel.c: change #if 1 into #if 0 if there is no <scsi/scsi.h>.
+- in mount/nfsmount.c: change #if 1 into #if 0 if there is no inet_aton().
+- in sys-utils/ipcs.c: change #if 0 into #if 1 if <linux/linkage.h> is needed.
+- in sys-utils/cytune.c: change #if 0 into #if 1 if <linux/tqueue.h> is needed.
+
+elsewhere: tell util-linux@math.uio.no about it.
+
+
+If you have runtime problems:
+
+- with non-ASCII characters: perhaps you forgot to set LC_CTYPE or LC_ALL?
+  (For example, in Norway one can say  LC_ALL=no_NO; export LC_ALL  and
+   then various utilities will treat Scandinavian non-ASCII letters as
+   letters.)
+
+otherwise: tell util-linux@math.uio.no about it.
+
diff --git a/LSM b/LSM
index 0906306c08e279ba3a5c3e9c5a2d6d8990bc5590..41edbbf3735a6f78cd114ff0fb9177ef45a6c87c 100644 (file)
--- a/LSM
+++ b/LSM
@@ -1,22 +1,23 @@
 Begin3
 Title:          util-linux: Miscellaneous utilities for Linux
-Version:        2.8
+Version:        2.9g
 Description:   agetty arch cal cfdisk chfn chkdupexe chsh
                clear hwclock col colcrt colrm column ctrlaltdel
-               cytune ddate dmesg dsplit fastboot fasthalt fdformat
+               cytune ddate dmesg fastboot fasthalt fdformat
                fdisk fsck.minix getopt halt hexdump ipcrm ipcs
                kbdrate kill last logger login look mcookie mesg mkfs
                mkfs.minix mkswap more mount namei passwd ramsize rdev
                readprofile reboot renice reset rev rootflags script
                 setfdprm setsid setterm sfdisk shutdown simpleinit sln
-               strings swapdev swapoff swapon tsort tunelp ul umount
+               swapdev swapoff swapon tsort tunelp ul umount
                vidmode vipw wall whereis write
 
 Keywords:       essential utilities
 Author:         several
-Maintained-by:  Nicolai Langfeldt <util-linux@math.uio.no> and others
-Primary-site:   ftp.math.uio.no /pub/linux
-                ~567k util-linux-2.8.tar.gz
+Maintained-by:  Andries Brouwer <util-linux@math.uio.no> and others
+Primary-site:   ftp.win.tue.nl /pub/linux/util
+Alternate-site: ftp.math.uio.no /pub/linux
+                ~567k util-linux-2.9g.tar.gz
 Alternate-site: sunsite.uio.no /pub/unix/linux/packages/util-linux
 Alternate-site: sunsite.unc.edu /pub/Linux/system/misc
 Alternate-site: tsx-11.mit.edu /pub/linux/packages/utils
index 623bd5204a49cd3f7f536edefa7d515f431b85b5..623b778835f07d4f87382483263f1224e311c28f 100644 (file)
@@ -1,19 +1,6 @@
-util-linux is maintained by a group of people, all reachable at
-util-linux@math.uio.no.
+util-linux is maintained by a group of people
+(Rik, Andries, Peter, Michael, Erik, Nicolai),
+all reachable at util-linux@math.uio.no.
 
-Some have specific interests, others just do everything else.
-
-This is a partial list of interests:
-
-Rik: Founding father
-Andries: *fdisk, mount, ...
-Peter: login, passwd, simpleinit, agetty, last, newgrp, shutdown,
-       domainname, ctrlaltdel
-Michael: Spirit of advice
-Erik: General hackery
-Nicolai: mail-queue processor (batch oriented)
-
-Bryan: hwclock master, he's not on the list but the mail queue
-  processor forwards mail to him.      
-
-Unassigned programs (defaulting to Nicolai): chfn, chsh, write, wall, ...
+Bryan, the hwclock master, is not on the list
+but the mail queue processor forwards mail to him.     
diff --git a/MCONFIG b/MCONFIG
index 2823988ef4c6b5d373518b99859f759dd5c79db4..147fc1ae2e0df7b4f7560e655fbd79ff56326f30 100644 (file)
--- a/MCONFIG
+++ b/MCONFIG
@@ -1,32 +1,32 @@
 # MCONFIG -- Configuration stuff for util-linux
 # Created: Sat Feb  4 15:50:30 1995
-# Revised: Sun Nov 10 20:10:13 1996 by faith@cs.unc.edu
 # Copyright 1995 Rickard E. Faith (faith@cs.unc.edu)
 
+# For a user-mode install, make (at least) three changes:
+#  - remove the `-o root' part in INSTALLSUID
+#  - set USE_TTY_GROUP=no
+#  - define DESTDIR
+
 # Select for CPU one of intel, alpha, sparc, arm, m68k, mips
 CPU=$(shell uname -m | sed s/i.86/intel/)
 
 # if HAVE_LIBCRYPT is "yes" -lcrypt will be used
-HAVE_LIBCRYPT=no
-# HAVE_LIBCRYPT=yes
+HAVE_LIBCRYPT=yes
 
 # If HAVE_PAM is set to "yes", then login, chfn, chsh, and newgrp
 # will use PAM for authentication. Additionally, passwd will not be
 # installed as it is not PAM aware.
 HAVE_PAM=no
-#HAVE_PAM=yes
 
 # If HAVE_SHADOW is set to "yes", then login, chfn, chsh, newgrp, passwd,
 # and vipw will not be built or installed from the login-utils
 # subdirectory.  
-HAVE_SHADOW=no
-#HAVE_SHADOW=yes
+HAVE_SHADOW=yes
 
 # If HAVE_PASSWD is set to "yes", then passwd will not be built or
 # installed from the login-utils subdirectory (but login, chfn, chsh,
 # newgrp, and vipw *will* be installed).
 HAVE_PASSWD=no
-#HAVE_PASSWD=yes
 
 # If you use chfn and chsh from this package, REQUIRE_PASSWORD will require
 # non-root users to enter the account password before updating /etc/passwd.
@@ -44,21 +44,18 @@ ONLY_LISTED_SHELLS=yes
 # be built or installed from the login-utils subdirectory.  (The shutdown
 # and halt that come with the SysVinit package should be used with the init
 # found in that package.)
-#HAVE_SYSVINIT=no
 HAVE_SYSVINIT=yes
 
 # If HAVE_SYSVINIT_UTILS is set to "yes", then last, mesg, and wall will
 # not be built or installed from the login-utils subdirectory.  (The
 # shutdown and init from the SysVinit package do not depend on the last,
 # mesg, and wall from that package.)
-#HAVE_SYSVINIT_UTILS=no
 HAVE_SYSVINIT_UTILS=yes
 
 # If HAVE_GETTY is set to "yes", then agetty will not be built or
 # installed from the login-utils subdirectory.  Note that agetty can
 # co-exist with other gettys, so this option should never be used.
 HAVE_GETTY=no
-#HAVE_GETTY=yes
 
 # If USE_TTY_GROUP is set to "yes", then wall and write will be installed
 # setgid to the "tty" group, and mesg will only set the group write bit.
@@ -67,24 +64,18 @@ HAVE_GETTY=no
 # xterm will do it correctly if X is compiled with USE_TTY_GROUP set
 # properly.]
 USE_TTY_GROUP=yes
-#USE_TTY_GROUP=no
 
-# If HAVE_STRINGS is set to "yes", then strings won't be installed.  This
-# is the quick fix until the strings in GNU binutils is in wide use and has
-# internationalization support.
-#HAVE_STRINGS=no
-HAVE_STRINGS=yes
+# If HAVE_OPENPTY is set to "yes", then script will use the Unix98 ptys
+HAVE_OPENPTY=no
 
 # If HAVE_RESET is set to "yes", then reset won't be installed.  The version
 # of reset that comes with the ncurses package is less aggressive.
-#HAVE_RESET=no
 HAVE_RESET=yes
 
-# If HAVE_MOUNT is set to "yes", then mount won't be installed, since many
-# folks grab mount independenty of util-linux
-# When util-linux is released it always contains the very latest mount.
-HAVE_MOUNT=no
-# HAVE_MOUNT=yes
+# If HAVE_SLN is set to "yes", then sln won't be installed
+# (but the man page sln.8 will be installed anyway).
+# sln also comes with libc and glibc.
+HAVE_SLN=no
 
 CC=            gcc
 
@@ -99,11 +90,15 @@ else
   endif
 endif
 
-BSD= ../bsd
+ERR_O=$(LIB)/err.o
+
+LIB=../lib
 
 LDFLAGS   = -s
 WARNFLAGS = -Wall
-CFLAGS    = $(OPT) -I. -I$(BSD) $(WARNFLAGS) $(CURSESFLAGS) $(SLANGFLAGS) \
+
+CFLAGS    = $(OPT) -I. -I$(LIB) $(WARNFLAGS) \
+                       $(CURSESFLAGS) $(SLANGFLAGS) \
                        $(EXTRACFLAGS) \
                        -DSBINDIR=\"$(SBINDIR)\" \
                        -DUSRSBINDIR=\"$(USRSBINDIR)\" \
@@ -123,7 +118,7 @@ HAVE_NCURSES=yes
 # No such subdirectory - <curses.h> is the ncurses one.
 #   CURSESFLAGS=-DNCH=0
 # Pick your choice.
-CURSESFLAGS=-DNCH=0
+CURSESFLAGS=-I/usr/include/ncurses -DNCH=0
 LIBCURSES=-lncurses
 
 # Set HAVE_SLANG to yes if you have slang (and prefer to use that for cfdisk)
@@ -147,11 +142,11 @@ BINDIR=         $(DESTDIR)/bin
 VARPATH=       $(DESTDIR)/var
 LOGDIR=                $(DESTDIR)/var/log
 MANDIR=                $(DESTDIR)/usr/man
-MAN1DIR=       $(DESTDIR)/usr/man/man1
-MAN3DIR=       $(DESTDIR)/usr/man/man3
-MAN5DIR=       $(DESTDIR)/usr/man/man5
-MAN6DIR=       $(DESTDIR)/usr/man/man6
-MAN8DIR=       $(DESTDIR)/usr/man/man8
+MAN1DIR=       $(MANDIR)/man1
+MAN3DIR=       $(MANDIR)/man3
+MAN5DIR=       $(MANDIR)/man5
+MAN6DIR=       $(MANDIR)/man6
+MAN8DIR=       $(MANDIR)/man8
 INFODIR=       $(DESTDIR)/usr/info
 
 # Directory for shutdown, halt, reboot, etc.
@@ -169,7 +164,7 @@ BINMODE=    755
 MANMODE=       644
 DATMODE=       644
 INFOMODE=      644
-SUIDMODE=      4711
+SUIDMODE=      4755
 
 CHMOD=         chmod
 INSTALL=       install
index 5bbbdc25c3b3e8f4c437fb14e0c32978188d93ff..92c9cae5806d35c5d89c3464b18de20047f4d7f1 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -5,21 +5,18 @@
 # May be distributed under the terms of the GNU GPL.
 #
 
-VERSION=2.8
+VERSION=2.9
 
 include ./MCONFIG
 
-ifeq "$(HAVE_MOUNT)" "no"
-       MOUNTDIR=mount
-endif
-
-SUBDIRS= bsd \
-       getopt \
+SUBDIRS=lib \
+       getopt-1.0.3a \
        disk-utils \
        games \
        login-utils \
        misc-utils \
-       $(MOUNTDIR) \
+       mount \
+       fdisk \
        sys-utils \
        text-utils
 
diff --git a/attic/pidof.c b/attic/pidof.c
new file mode 100644 (file)
index 0000000..74709c7
--- /dev/null
@@ -0,0 +1,95 @@
+/* pid -- display the process id of a running command
+
+   Copyright (c) 1994 Salvatore Valente <svalente@mit.edu>
+   Copyright (c) 1996 Bruno Haible <haible@ilog.fr>
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+extern int* get_pids (char*, int);
+
+char version_string[] = "pid 1.0";
+char* program_name;
+
+int usage (int status)
+{
+  FILE* fp = (status == 0 ? stdout : stderr);
+  fprintf(fp, "Usage:  %s command ...\n", program_name);
+  return status;
+}
+
+static int compar_int (const void* i1, const void* i2)
+{
+  return *((int *)i1) - *((int *)i2);
+}
+
+int main (int argc, char *argv[])
+{
+  int i;
+  int *pids, *pids0;
+  int num_allpids = 0;
+  int *allpids = (int*)0;
+  int allpids_size = 0;
+
+  program_name = argv[0];
+
+  /* Argument processing. */
+  for (i = 1; i < argc; i++) {
+    char* arg = argv[i];
+    if (!strcmp(arg, "--help"))
+      return usage(0);
+    else if (!strcmp(arg, "--version")) {
+      printf("%s\n", version_string);
+      return 0;
+    }
+  }
+
+  /* Gather the pids. */
+  for (i = 1; i < argc; i++) {
+    char* arg = argv[i];
+    pids0 = pids = get_pids(arg, 1);
+    if (pids) {
+      while (*pids >= 0) {
+        int pid = *pids++;
+        if (num_allpids >= allpids_size) {
+          allpids_size = 2*allpids_size+1;
+          allpids = (int*) realloc(allpids, sizeof(int)*allpids_size);
+          if (!allpids) {
+            fprintf(stderr, "%s: out of memory\n", program_name);
+            exit(1);
+          }
+        }
+        allpids[num_allpids++] = pid;
+      }
+      free(pids0);
+    }
+  }
+
+  /* Sort them. */
+  if (num_allpids > 1)
+    qsort(allpids, num_allpids, sizeof(int), compar_int);
+
+  /* Print them. */
+  for (pids = allpids, i = num_allpids; i > 0; pids++, i--)
+    printf("%d\n", *pids);
+
+  return 0;
+}
similarity index 100%
rename from text-utils/strings.1
rename to attic/strings.1
similarity index 100%
rename from text-utils/strings.c
rename to attic/strings.c
diff --git a/bsd/Makefile b/bsd/Makefile
deleted file mode 100644 (file)
index 8783c5b..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-# Makefile -- Makefile for util-linux Linux utilities
-# Created: Sat Dec 26 20:09:40 1992
-# Revised: Fri Mar 10 21:20:41 1995 by faith@cs.unc.edu
-# Copyright 1992, 1993, 1994, 1995 Rickard E. Faith (faith@cs.unc.edu)
-#
-
-include ../MCONFIG
-
-all: err.o getopt.o
-err.o: err.c
-getopt.o: getopt.c
-
-.PHONY: clean distclean
-clean:
-       -rm -f *.o *~ core
-
-install install.shadow:
diff --git a/bsd/getopt.3 b/bsd/getopt.3
deleted file mode 100644 (file)
index c21a0a7..0000000
+++ /dev/null
@@ -1,210 +0,0 @@
-.\" Copyright (c) 1988, 1991 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.
-.\"
-.\"     @(#)getopt.3   6.16 (Berkeley) 4/19/91
-.\"
-.Dd April 19, 1991
-.Dt GETOPT 3
-.Os BSD 4.3
-.Sh NAME
-.Nm getopt
-.Nd get option letter from argv
-.Sh SYNOPSIS
-.Fd #include <stdlib.h>
-.Vt extern char *optarg
-.Vt extern int   optind
-.Vt extern int   opterr
-.Ft int
-.Fn getopt "int argc" "char * const *argv" "const char *optstring"
-.Sh DESCRIPTION
-The
-.Fn getopt
-function gets 
-the next
-.Em known
-option character from
-.Fa argv .
-An option character is
-.Em known
-if it has been specified in the string of accepted option characters,
-.Fa optstring .
-.Pp
-The option string
-.Fa optstring
-may contain the following characters; letters and
-letters followed by a colon to indicate an option argument
-is to follow. It does not matter to
-.Fn getopt
-if a following argument has leading white space.
-.Pp
-On return from
-.Fn getopt ,
-.Va optarg
-points to an option argument, if it is anticipated,
-and the variable
-.Va optind
-contains the index to the next
-.Fa argv
-argument for a subsequent call
-to
-.Fn getopt .
-.Pp
-The variable
-.Va opterr
-and
-.Va optind
-are both initialized to 1.
-In order to use
-.Fn getopt
-to evaluate multiple sets of arguments, or to evaluate a single set of
-arguments multiple times,
-.Va optind
-must be initialized to the number of argv entries to be skipped in each
-evaluation.
-.Pp
-The
-.Fn getopt
-function
-returns an
-.Dv EOF
-when the argument list is exhausted, or a non-recognized
-option is encountered.
-The interpretation of options in the argument list may be cancelled
-by the option
-.Ql --
-(double dash) which causes
-.Fn getopt
-to signal the end of argument processing and return an
-.Dv EOF . 
-When all options have been processed (i.e., up to the first non-option
-argument),
-.Fn getopt
-returns
-.Dv EOF .
-.Sh DIAGNOSTICS
-If the
-.Fn getopt
-function encounters a character not found in the string
-.Va optarg
-or detects
-a missing option argument
-it writes error message
-.Ql ?
-to the
-.Em stderr .
-Setting
-.Va opterr
-to a zero will disable these error messages.
-.Sh EXAMPLE
-.Bd -literal -compact
-extern char *optarg;
-extern int optind;
-int bflag, ch, fd;
-
-bflag = 0;
-while ((ch = getopt(argc, argv, "bf:")) != EOF)
-       switch(ch) {
-       case 'b':
-               bflag = 1;
-               break;
-       case 'f':
-               if ((fd = open(optarg, O_RDONLY, 0)) < 0) {
-                       (void)fprintf(stderr,
-                               "myname: unable to read file %s.\en", optarg);
-                       exit(1) ;
-               }
-               break;
-       case '?':
-       default:
-               usage();
-}
-argc -= optind;
-argv += optind;
-.Ed
-.Sh HISTORY
-The
-.Fn getopt
-function appeared
-.Bx 4.3 .
-.Sh BUGS
-Option arguments are allowed to begin with
-.Dq Li \- ;
-this is reasonable but
-reduces the amount of error checking possible.
-.Pp
-A single dash
-.Dq Li -
-may be specified as an character in
-.Fa optstring ,
-however it should
-.Em never
-have an argument associated with it.
-This allows
-.Fn getopt
-to be used with programs that expect
-.Dq Li -
-as an option flag.
-This practice is wrong, and should not be used in any current development.
-It is provided for backward compatibility
-.Em only .
-By default, a single dash causes
-.Fn getopt
-to return
-.Dv EOF .
-This is, we believe, compatible with System V.
-.Pp
-It is also possible to handle digits as option letters.
-This allows
-.Fn getopt
-to be used with programs that expect a number
-.Pq Dq Li \&-\&3
-as an option.
-This practice is wrong, and should not be used in any current development.
-It is provided for backward compatibility
-.Em only .
-The following code fragment works fairly well.
-.Bd -literal -offset indent
-int length;
-char *p;
-
-while ((c = getopt(argc, argv, "0123456789")) != EOF)
-       switch (c) {
-       case '0': case '1': case '2': case '3': case '4':
-       case '5': case '6': case '7': case '8': case '9':
-               p = argv[optind - 1];
-               if (p[0] == '-' && p[1] == ch && !p[2])
-                       length = atoi(++p);
-               else
-                       length = atoi(argv[optind] + 1);
-               break;
-       }
-}
-.Ed
diff --git a/bsd/getopt.c b/bsd/getopt.c
deleted file mode 100644 (file)
index be621bd..0000000
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Copyright (c) 1987 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.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-/*
- * get option letter from argument vector
- */
-int    opterr = 1,             /* if error message should be printed */
-       optind = 1,             /* index into parent argv vector */
-       optopt;                 /* character checked for validity */
-char   *optarg;                /* argument associated with option */
-
-#define        BADCH   (int)'?'
-#define        EMSG    ""
-
-int
-getopt(nargc, nargv, ostr)
-       int nargc;
-       char * const *nargv;
-       const char *ostr;
-{
-       static char *place = EMSG;              /* option letter processing */
-       register char *oli;                     /* option letter list index */
-       char *p;
-
-       if (!*place) {                          /* update scanning pointer */
-               if (optind >= nargc || *(place = nargv[optind]) != '-') {
-                       place = EMSG;
-                       return(EOF);
-               }
-               if (place[1] && *++place == '-') {      /* found "--" */
-                       ++optind;
-                       place = EMSG;
-                       return(EOF);
-               }
-       }                                       /* option letter okay? */
-       if ((optopt = (int)*place++) == (int)':' ||
-           !(oli = index(ostr, optopt))) {
-               /*
-                * if the user didn't specify '-' as an option,
-                * assume it means EOF.
-                */
-               if (optopt == (int)'-')
-                       return(EOF);
-               if (!*place)
-                       ++optind;
-               if (opterr) {
-                       if (!(p = rindex(*nargv, '/')))
-                               p = *nargv;
-                       else
-                               ++p;
-                       (void)fprintf(stderr, "%s: illegal option -- %c\n",
-                           p, optopt);
-               }
-               return(BADCH);
-       }
-       if (*++oli != ':') {                    /* don't need argument */
-               optarg = NULL;
-               if (!*place)
-                       ++optind;
-       }
-       else {                                  /* need an argument */
-               if (*place)                     /* no white space */
-                       optarg = place;
-               else if (nargc <= ++optind) {   /* no arg */
-                       place = EMSG;
-                       if (!(p = rindex(*nargv, '/')))
-                               p = *nargv;
-                       else
-                               ++p;
-                       if (opterr)
-                               (void)fprintf(stderr,
-                                   "%s: option requires an argument -- %c\n",
-                                   p, optopt);
-                       return(BADCH);
-               }
-               else                            /* white space */
-                       optarg = nargv[optind];
-               place = EMSG;
-               ++optind;
-       }
-       return(optopt);                         /* dump back option letter */
-}
index d21cedb9ed30f8d205c693f4a2bc76938aaa3c3a..aec38630a943d0e80a8253eaf7327f460e134c72 100644 (file)
@@ -23,48 +23,12 @@ 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
-ifneq "$(CPU)" "m68k"
-MAN8:=$(MAN8) fdisk.8 cfdisk.8 sfdisk.8
-SBIN:=$(SBIN) fdisk cfdisk sfdisk
-endif
-else
-MAN8:=$(MAN8) fdisk.8
-SBIN:=$(SBIN) fdisk
 endif
 
 # Where to put datebase files?
 
 all: $(SBIN) $(USRBIN)
 
-cfdisk.o: cfdisk.c
-ifeq "$(HAVE_SLANG)" "yes"
-       $(CC) -c $(CFLAGS) -DSLCURSES=1 $< -o $@
-else
-ifeq "$(HAVE_NCURSES)" "yes"
-       $(CC) -c $(CFLAGS) $< -o $@
-else
-       :
-endif
-endif
-
-cfdisk: cfdisk.o llseek.o
-ifeq "$(HAVE_SLANG)" "yes"
-       $(CC) $(LDFLAGS) $^ -o $@ $(LIBSLANG)
-else
-ifeq "$(HAVE_NCURSES)" "yes"
-       $(CC) $(LDFLAGS) $^ -o $@ $(LIBCURSES) -lm
-else
-       @echo $@ not made since it requires ncurses or slang
-endif
-endif
-
-# not installed by default
-activate: sfdisk
-       rm -f activate
-       ln -s sfdisk activate
-
-# Rules for everything else
-
 fdformat: fdformat.o
 fsck.minix: fsck.minix.o
 fsck.minix.o: fsck.minix.c bitops.h
@@ -73,17 +37,6 @@ mkfs.minix: mkfs.minix.o
 mkfs.minix.o: mkfs.minix.c bitops.h
 mkswap: mkswap.o
 setfdprm: setfdprm.o
-sfdisk: sfdisk.o
-
-ifeq "$(CPU)" "sparc"
-fdisk: fdisk.o fdisklabel.o fdisksunlabel.o llseek.o
-fdisksunlabel.o: fdisksunlabel.c fdisksunlabel.h fdisk.h
-else
-fdisk: fdisk.o fdisklabel.o llseek.o
-endif
-
-fdisk.o: fdisk.c fdisk.h
-fdisklabel.o: fdisklabel.c fdisk.h fdisklabel.h
 
 install: all
        $(INSTALLDIR) $(SBINDIR) $(USRBINDIR) $(ETCDIR)
diff --git a/disk-utils/cfdisk.8.bak b/disk-utils/cfdisk.8.bak
deleted file mode 100644 (file)
index cb23149..0000000
+++ /dev/null
@@ -1,407 +0,0 @@
-.\" cfdisk.8 -- man page for cfdisk
-.\" Copyright 1994 Kevin E. Martin (martin@cs.unc.edu)
-.\"
-.\" Permission is granted to make and distribute verbatim copies of this
-.\" manual provided the copyright notice and this permission notice are
-.\" preserved on all copies.
-.\"
-.\" Permission is granted to copy and distribute modified versions of this
-.\" manual under the conditions for verbatim copying, provided that the
-.\" entire resulting derived work is distributed under the terms of a
-.\" permission notice identical to this one.
-.\"
-.\" " for hilit mode
-.TH CFDISK 8 "25 April 1994" "The BOGUS Linux Release" "Linux Programmer's Manual"
-.SH NAME
-cfdisk \- Curses based disk partition table manipulator for Linux
-.SH SYNOPSIS
-.BI "cfdisk [ \-avz ] [ \-c " cylinders " ] [ \-h " heads " ]"
-.BI "[ \-s " sectors-per-track " ] [ -P " opt " ] [ " device " ]"
-.SH DESCRIPTION
-.B cfdisk
-is a curses based program for partitioning a hard disk drive.  The
-.I device
-can be any one of the following:
-.sp
-.nf
-.RS
-/dev/hda [default]
-/dev/hdb
-/dev/sda
-/dev/sdb
-/dev/sdc
-/dev/sdd
-.RE
-.fi
-
-.B cfdisk
-first tries to read the geometry of the hard disk.  If it fails, an
-error message is displayed and
-.B cfdisk
-exits.  This should only happen when partitioning a SCSI drive on an
-adapter without a BIOS.  To correct this problem, you can set the
-.IR cylinders ", " heads " and " sectors-per-track
-on the command line.  Next,
-.B cfdisk
-tries to read the current partition table from the disk drive.  If it
-is unable to figure out the partition table, an error is displayed and
-the program will exit.  This might also be caused by incorrect
-geometry information, and can be overridden on the command line.
-Another way around this problem is with the
-.B \-z
-option.  This will ignore the partition table on the disk.
-
-The main display is composed of four sections, from top to bottom: the
-header, the partitions, the command line and a warning line.  The
-header contains the program name and version number followed by the
-disk drive and its geometry.  The partitions section always displays
-the current partition table.  The command line is the place where
-commands and text are entered.  The available commands are usually
-displayed in brackets.  The warning line is usually empty except when
-there is important information to be displayed.  The current partition
-is highlighted with reverse video (or an arrow if the
-.B \-a
-option is given).  All partition specific commands apply to the
-current partition.
-
-The format of the partition table in the partitions section is, from
-left to right: Name, Flags, Partition Type, Filesystem Type and Size.
-The name is the partition device name.  The flags can be
-.IR Boot ,
-which designates a bootable partition or
-.IR NC ,
-which stands for "Not Compatible with DOS or OS/2".  DOS, OS/2 and
-possibly other operating systems require the first sector of the first
-partition on the disk and all logical partitions to begin on the
-second head.  This wastes the second through the last sector of the
-first track of the first head (the first sector is taken by the
-partition table itself).
-.B cfdisk
-allows you to recover these "lost" sectors with the maximize command
-.RB ( m ).
-.I Note:
-.BR fdisk (8)
-and some early versions of DOS create all partitions with the number
-of sectors already maximized.  For more information, see the maximize
-command below.  The partition type can be one of
-.IR Primary " or " Logical .
-For unallocated space on the drive, the partition type can also be
-.IR Pri/Log ,
-or empty (if the space is unusable).  The filesystem type section
-displays the name of the filesystem used on the partition, if known.
-If it is unknown, then
-.I Unknown
-and the hex value of the filesystem type are displayed.  A special
-case occurs when there are sections of the disk drive that cannot be
-used (because all of the primary partitions are used).  When this is
-detected, the filesystem type is displayed as
-.IR Unusable .
-The size field displays the size of the partition in megabytes (by
-default).  It can also display the size in sectors and cylinders (see
-the change units command below).  If an asterisks
-.RB ( * )
-appears after the size, this means that the partition is not aligned
-on cylinder boundaries.
-.SH "DOS 6.x WARNING"
-
-The DOS 6.x FORMAT command looks for some information in the first
-sector of the data area of the partition, and treats this information
-as more reliable than the information in the partition table.  DOS
-FORMAT expects DOS FDISK to clear the first 512 bytes of the data area
-of a partition whenever a size change occurs.  DOS FORMAT will look at
-this extra information even if the /U flag is given -- we consider
-this a bug in DOS FORMAT and DOS FDISK.
-
-The bottom line is that if you use cfdisk or fdisk to change the size of a
-DOS partition table entry, then you must also use
-.B dd
-to zero the first 512 bytes of that partition before using DOS FORMAT to
-format the partition.  For example, if you were using cfdisk to make a DOS
-partition table entry for /dev/hda1, then (after exiting fdisk or cfdisk
-and rebooting Linux so that the partition table information is valid) you
-would use the command "dd if=/dev/zero of=/dev/hda1 bs=512 count=1" to zero
-the first 512 bytes of the partition.
-.B BE EXTREMELY CAREFUL
-if you use the
-.B dd
-command, since a small typo can make all of the data on your disk useless.
-
-.B BE EXTREMELY CAREFUL
-if you use the
-.B dd
-command, since a small typo can make all of the data on your disk useless.
-
-For best resutls, you should always use an OS-specific partition table
-program.  For example, you should make DOS partitions with the DOS FDISK
-program and Linux partitions with the Linux fdisk or Linux cfdisk program.
-
-.SH COMMANDS
-.B cfdisk
-commands can be entered by pressing the desired key (pressing
-.I Enter
-after the command is not necessary).  Here is a list of the available
-commands:
-.TP
-.B b
-Toggle bootable flag of the current partition.  This allows you to
-select which primary partition is bootable on the drive.
-.TP
-.B d
-Delete the current partition.  This will convert the current partition
-into free space and merge it with any free space immediately
-surrounding the current partition.  A partition already marked as free
-space or marked as unusable cannot be deleted.
-.TP
-.B g
-Change the disk geometry (cylinders, heads, or sectors-per-track).
-.B WARNING:
-This option should only be used by people who know what they are
-doing.  A command line option is also available to change the disk
-geometry.  While at the change disk geometry command line, you can
-choose to change cylinders
-.RB ( c ),
-heads
-.RB ( h ),
-and sectors per track
-.RB ( s ).
-The default value will be printed at the prompt which you can accept
-by simply pressing the
-.I Enter
-key, or you can exit without changes by pressing the
-.I ESC
-key.  If you want to change the default value, simply enter the
-desired value and press
-.IR Enter .
-The altered disk parameter values do not take effect until you return
-the main menu (by pressing
-.IR Enter " or " ESC
-at the change disk geometry command line.  If you change the geometry
-such that the disk appears larger, the extra sectors are added at the
-end of the disk as free space.  If the disk appears smaller, the
-partitions that are beyond the new last sector are deleted and the
-last partition on the drive (or the free space at the end of the
-drive) is made to end at the new last sector.
-.TP
-.B h
-Print the help screen.
-.TP
-.B m
-Maximize disk usage of the current partition.  This command will
-recover the the unused space between the partition table and the
-beginning of the partition, but at the cost of making the partition
-incompatible with DOS, OS/2 and possibly other operating systems.
-This option will toggle between maximal disk usage and DOS, OS/2,
-etc. compatible disk usage.  The default when creating a partition is
-to create DOS, OS/2, etc. compatible partitions.
-.TP
-.B n
-Create new partition from free space.  If the partition type is
-.IR Primary " or " Logical ,
-a partition of that type will be created, but if the partition type is
-.IR Pri/Log ,
-you will be prompted for the type you want to create.  Be aware that
-(1) there are only four slots available for primary partitions and (2)
-since there can be only one extended partition, which contains all of
-the logical drives, all of the logical drives must be contiguous (with
-no intervening primary partition).
-.B cfdisk
-next prompts you for the size of the partition you want to create.
-The default size, equal to the entire free space of the current
-partition, is display in megabytes.  You can either press the
-.I Enter
-key to accept the default size or enter a different size at the
-prompt.
-.B cfdisk
-accepts size entries in megabytes
-.RB ( M )
-[default], kilobytes
-.RB ( K ),
-cylinders
-.RB ( C )
-and sectors
-.RB ( S )
-by entering the number immediately followed by one of
-.RB ( M ", " K ", " C " or " S ).
-If the partition fills the free space available, the partition is
-created and you are returned to the main command line.  Otherwise, the
-partition can be created at the beginning or the end of the free
-space, and
-.B cfdisk
-will ask you to choose where to place the partition.  After the
-partition is created,
-.B cfdisk
-automatically adjusts the other partition's partition types if all of
-the primary partitions are used.
-.TP
-.B p
-Print the partition table to the screen or to a file. There are
-several different formats for the partition that you can choose from:
-.sp
-.RS
-.TP
-.B r
-Raw data format (exactly what would be written to disk)
-.TP
-.B s
-Partition table in sector order format
-.TP
-.B t
-Partition table in raw format
-.RE
-
-.RS
-The
-.I raw data format
-will print the sectors that would be written to disk if a
-.BR w rite
-command is selected.  First, the primary partition table is printed,
-followed by the partition tables associated with each logical
-partition.  The data is printed in hex byte by byte with 16 bytes per
-line.
-
-The
-.I partition table in sector order format
-will print the partition table ordered by sector number.  The fields,
-from left to right, are the number of the partition, the partition
-type, the first sector, the last sector, the offset from the first
-sector of the partition to the start of the data, the length of the
-partition, the filesystem type (with the hex value in parenthesis),
-and the flags (with the hex value in parenthesis).  In addition to the
-primary and logical partitions, free and unusable space is printed and
-the extended partition is printed before the first logical partition.
-
-If a partition does not start or end on a cylinder boundary or if the
-partition length is not divisible by the cylinder size, an asterisks
-.RB ( * )
-is printed after the non-aligned sector number/count.  This usually
-indicates that a partition was created by an operating system that
-either does not align partitions to cylinder boundaries or that used
-different disk geometry information.  If you know the disk geometry of
-the other operating system, you could enter the geometry information
-with the change geometry command
-.RB ( g ).
-
-For the first partition on the disk and for all logical partitions, if
-the offset from the beginning of the partition is not equal to the
-number of sectors per track (i.e., the data does not start on the
-first head), a number sign
-.RB ( # )
-is printed after the offset.  For the remaining partitions, if the
-offset is not zero, a number sign will be printed after the offset.
-This corresponds to the
-.I NC
-flag in the partitions section of the main display.
-
-The
-.I partition table in raw format
-will print the partition table ordered by partition number.  It will
-leave out all free and unusable space.  The fields, from left to
-right, are the number of the partition, the flags (in hex), the
-starting head, sector and cylinder, the filesystem ID (in hex), the
-ending head, sector and cylinder, the starting sector in the partition
-and the number of sectors in the partition.  The information in this
-table can be directly translated to the
-.IR "raw data format" .
-
-The partition table entries only have 10 bits available to represent
-the starting and ending cylinders.  Thus, when the absolute starting
-(ending) sector number is on a cylinder greater than 1023, the maximal
-values for starting (ending) head, sector and cylinder are printed.
-This is the method used by OS/2, and thus fixes the problems
-associated with OS/2's fdisk rewriting the partition table when it is
-not in this format.  Since Linux and OS/2 use absolute sector counts,
-the values in the starting and ending head, sector and cylinder are
-not used.
-.RE
-.TP
-.B q
-Quit program.  This will exit the program without writing any data to
-disk.
-.TP
-.B t
-Change the filesystem type.  By default, new partitions are created as
-.I Linux
-partitions, but since
-.B cfdisk
-can create partitions for other operating systems, change partition
-type allows you to enter the hex value of the filesystem you desire.
-A list of the know filesystem types is displayed.  You can type in the
-filesystem type at the prompt or accept the default filesystem type
-.RI [ Linux ].
-.TP
-.B u
-Change units of the partition size display.  It will rotate through
-megabytes, sectors and cylinders.
-.TP
-.B W
-Write partition table to disk (must enter an upper case W).  Since
-this might destroy data on the disk, you must either confirm or deny
-the write by entering `yes' or `no'.  If you enter `yes',
-.B cfdisk
-will write the partition table to disk and the tell the kernel to
-re-read the partition table from the disk.  The re-reading of the
-partition table works is most cases, but I have seen it fail.  Don't
-panic.  It will be correct after you reboot the system.  In all cases,
-I still recommend rebooting the system--just to be safe.
-.TP
-.I Up Arrow
-.TP
-.I Down Arrow
-Move cursor to the previous or next partition.  If there are more
-partitions than can be displayed on a screen, you can display the next
-(previous) set of partitions by moving down (up) at the last (first)
-partition displayed on the screen.
-.TP
-.I CTRL-L
-Redraws the screen.  In case something goes wrong and you cannot read
-anything, you can refresh the screen from the main command line.
-.TP
-.B ?
-Print the help screen.
-
-.RE
-All of the commands can be entered with either upper or lower case
-letters (except for
-.BR W rites).
-When in a sub-menu or at a prompt to enter a filename, you can hit the
-.I ESC
-key to return to the main command line.
-.SH OPTIONS
-.TP
-.B \-a
-Use an arrow cursor instead of reverse video for highlighting the
-current partition.
-.TP
-.B \-v
-Print the version number and copyright.
-.TP
-.B \-z
-Start with zeroed partition table.  This option is useful when you
-want to repartition your entire disk.
-.I Note:
-this option does not zero the partition table on the disk; rather, it
-simply starts the program without reading the existing partition
-table.
-.TP
-.BI \-c " cylinders"
-.TP
-.BI \-h " heads"
-.TP
-.BI \-s " sectors-per-track"
-Override the number of cylinders, heads and sectors per track read
-from the BIOS.  If your BIOS or adapter does not supply this
-information or if it supplies incorrect information, use these options
-to set the disk geometry values.
-.TP
-.BI \-P " opt"
-Prints the partition table in specified formats.
-.I opt
-can be one or more of "r", "s" or "t".  See the
-.BR p rint
-command (above) for more information on the print formats.
-.SH "SEE ALSO"
-fdisk(8)
-.SH BUGS
-The current version does not support multiple disks (future addition).
-.SH AUTHOR
-Kevin E. Martin (martin@cs.unc.edu)
diff --git a/disk-utils/cfdisk.c.bak b/disk-utils/cfdisk.c.bak
deleted file mode 100644 (file)
index 3b9f22f..0000000
+++ /dev/null
@@ -1,2066 +0,0 @@
-/****************************************************************************
- *
- *     CFDISK
- *
- * cfdisk is a curses based disk drive partitioning program that can
- * create partitions for a wide variety of operating systems including
- * Linux, MS-DOS and OS/2.
- *
- * cfdisk was inspired by the fdisk program, by A. V. Le Blanc
- * (LeBlanc@mcc.ac.uk).
- *
- *     Copyright (C) 1994 Kevin E. Martin (martin@cs.unc.edu)
- *
- * cfdisk is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * cfdisk is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with cfdisk; if not, write to the Free Software Foundation,
- * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Created:    Fri Jan 28 22:46:58 1994, martin@cs.unc.edu
- *
- ****************************************************************************/
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <unistd.h>
-#include <ctype.h>
-#include <errno.h>
-#include <getopt.h>
-#include <fcntl.h>
-#include <curses.h>
-#include <signal.h>
-#include <math.h>
-#include <sys/ioctl.h>
-#include <linux/genhd.h>
-#include <linux/hdreg.h>
-#include <linux/fs.h>          /* for BLKRRPART */
-
-typedef long ext2_loff_t;
-extern ext2_loff_t ext2_llseek(unsigned int fd,
-                              ext2_loff_t offset,
-                              unsigned int origin);
-
-#define VERSION "0.8 BETA (>2GB)"
-
-#define DEFAULT_DEVICE "/dev/hda"
-#define ALTERNATE_DEVICE "/dev/sda"
-
-#define LINE_LENGTH 80
-#define MAXIMUM_PARTS 60
-
-#define SECTOR_SIZE 512
-
-#define MAX_CYLINDERS 65535
-#define MAX_HEADS 255
-#define MAX_SECTORS 63
-
-#define ACTIVE_FLAG 0x80
-#define PART_TABLE_FLAG 0xAA55
-
-#define UNUSABLE -1
-#define FREE_SPACE 0x00
-#define EXTENDED 0x05
-#define LINUX_MINIX 0x81
-#define LINUX_SWAP 0x82
-#define LINUX 0x83
-
-#define ADD_EXISTS "This partition is already in use"
-#define ADD_UNUSABLE "This partition is unusable"
-#define DEL_EMPTY "Cannot delete an empty partition"
-#define ID_EMPTY "Cannot change FS Type to empty"
-#define ID_EXT "Cannot change FS Type to extended"
-#define NEED_EXT "No room to create the extended partition"
-#define NO_FLAGS "Cannot make this partition bootable"
-#define NO_MORE_PARTS "No more partitions"
-#define PRINT_OPEN_ERR "Cannot open file '%s'"
-#define TWO_EXTENDEDS "Cannot create logical drive here -- would create two extended partitions"
-#define TYPE_EMPTY "Cannot change the type of an empty partition"
-#define BAD_COMMAND "Illegal command"
-#define MAX_UNMAXABLE "Cannot maximize this partition"
-#define BAD_OPEN "Cannot open disk drive"
-#define BAD_SEEK "Cannot seek on disk drive"
-#define BAD_READ "Cannot read disk drive"
-#define BAD_WRITE "Cannot write disk drive"
-#define BAD_GEOMETRY "Cannot read disk drive geometry"
-#define BAD_PRIMARY "Bad primary partition"
-#define BAD_LOGICAL "Bad logical partition"
-#define BAD_CYLINDERS "Illegal cylinders value"
-#define BAD_HEADS "Illegal heads value"
-#define BAD_SECTORS "Illegal sectors value"
-#define WRITE_WARN "Warning!!  This may destroy data on your disk!"
-#define YES_NO "Please enter `yes' or `no'"
-#define WRITING_PART "Writing partition table to disk..."
-#define YES_WRITE "Wrote partition table to disk"
-#define NO_WRITE "Did not write partition table to disk"
-#define RRPART_FAILED "Wrote partition table, but re-read table failed.  Reboot to update table."
-
-#define PRI_OR_LOG -1
-#define PRIMARY -2
-#define LOGICAL -3
-
-#define COL_ID_WIDTH 20
-
-#define CR '\015'
-#define ESC '\033'
-#define DEL '\177'
-#define BELL '\007'
-/* '\014' == ^L */
-#define REDRAWKEY '\014'
-
-/* Display units */
-#define MEGABYTES 1
-#define SECTORS 2
-#define CYLINDERS 3
-
-#define GS_DEFAULT -1
-#define GS_ESCAPE -2
-
-#define PRINT_RAW_TABLE 1
-#define PRINT_SECTOR_TABLE 2
-#define PRINT_PARTITION_TABLE 4
-
-#define IS_PRIMARY(p) ((p) >= 0 && (p) < 4)
-#define IS_LOGICAL(p) ((p) > 3)
-
-#define round_int(d) ((double)((int)(d+0.5)))
-#define ceiling(d) ((double)(((d) != (int)(d)) ? (int)(d+1.0) : (int)(d)))
-
-#define set_hsc(h,s,c,sector) \
-{ \
-      s = sector % sectors + 1;        \
-      sector /= sectors;       \
-      h = sector % heads;      \
-      sector /= heads;         \
-      c = sector & 0xFF;       \
-      s |= (sector >> 2) & 0xC0;\
-}
-
-#define ALIGNMENT 2
-typedef union {
-    struct {
-       unsigned char align[ALIGNMENT];
-       unsigned char b[SECTOR_SIZE];
-    } c;
-    struct {
-       unsigned char align[ALIGNMENT];
-       unsigned char buffer[0x1BE];
-       struct partition part[4];
-       unsigned short flag;
-    } p;
-} partition_table;
-
-typedef struct {
-    int first_sector;  /* first sector in partition */
-    int last_sector;   /* last sector in partition */
-    int offset;                /* offset from first sector to start of data */
-    int flags;         /* active == 0x80 */
-    int id;            /* filesystem type */
-    int num;           /* number of partition -- primary vs. logical */
-} partition_info;
-
-char *disk_device = DEFAULT_DEVICE;
-int fd;
-int heads = 0;
-int sectors = 0;
-int cylinders = 0;
-int changed = FALSE;
-int opened = FALSE;
-
-partition_info p_info[MAXIMUM_PARTS];
-partition_info ext_info;
-int num_parts = 0;
-
-int logical = 0;
-int logical_sectors[MAXIMUM_PARTS];
-
-__sighandler_t old_SIGINT, old_SIGTERM;
-
-int arrow_cursor = FALSE;
-int display_units = MEGABYTES;
-int zero_table = FALSE;
-int print_only = 0;
-
-/* Curses screen information */
-int cur_part = 0;
-int warning_last_time = FALSE;
-int defined = FALSE;
-int COLUMNS = 80;
-int NUM_ON_SCREEN = 1;
-
-/* Y coordinates */
-int HEADER_START = 0;
-int DISK_TABLE_START = 5;
-int WARNING_START = 23;
-int COMMAND_LINE_Y = 21;
-
-/* X coordinates */
-int NAME_START = 4;
-int FLAGS_START = 16;
-int PTYPE_START = 30;
-int FSTYPE_START = 45;
-int SIZE_START = 70;
-int COMMAND_LINE_X = 5;
-
-#define NUM_PART_TYPES 256
-char *partition_type[NUM_PART_TYPES] = {
-    [LINUX_MINIX] = "Linux/MINIX",
-    [LINUX_SWAP]  = "Linux Swap",
-    [LINUX]       = "Linux",
-    [FREE_SPACE]  = "Free Space",
-    [EXTENDED]    = "Extended",
-    [0x01]        = "DOS 12-bit FAT",
-    [0x04]        = "DOS 16-bit < 32Mb",
-    [0x06]        = "DOS 16-bit >=32Mb",
-    [0x07]        = "OS/2 HPFS",
-    [0x0A]        = "OS/2 Boot Manager",
-    [0xA5]        = "BSD/386",
-
-/* The rest of these are taken from A. V. Le Blanc's (LeBlanc@mcc.ac.uk)
- * fdisk program.  I do not know where they came from, but I include
- * them for completeness.
- */
-
-    [0x02]        = "XENIX root",
-    [0x03]        = "XENIX usr",
-    [0x08]        = "AIX",
-    [0x09]        = "AIX bootable",
-    [0x40]        = "Venix 80286",
-    [0x51]        = "Novell?",
-    [0x52]        = "Microport",
-    [0x63]        = "GNU HURD",
-    [0x64]        = "Novell",
-    [0x75]        = "PC/IX",
-    [0x80]        = "Old MINIX",
-    [0x93]        = "Amoeba",
-    [0x94]        = "Amoeba BBT",
-    [0xB7]        = "BSDI fs",
-    [0xB8]        = "BSDI swap",
-    [0xC7]        = "Syrinx",
-    [0xDB]        = "CP/M",
-    [0xE1]        = "DOS access",
-    [0xE3]        = "DOS R/O",
-    [0xF2]        = "DOS secondary",
-    [0xFF]        = "BBT"
-};
-
-void fdexit(int ret)
-{
-    if (opened)
-       close(fd);
-
-    if (changed) {
-       fprintf(stderr, "Disk has been changed.\n");
-       fprintf(stderr, "Reboot the system to ensure the partition "
-                       "table is correctly updated.\n");
-       
-       fprintf( stderr, "\nWARNING: If you have created or modified any\n"
-                        "DOS 6.x partitions, please see the cfdisk manual\n"
-                        "page for additional information.\n" );
-    }
-
-
-    exit(ret);
-}
-
-int get_string(char *str, int len, char *def)
-{
-    char c;
-    int i = 0;
-    int x, y;
-    int use_def = FALSE;
-
-    getyx(stdscr, y, x);
-    clrtoeol();
-
-    str[i] = 0;
-
-    if (def != NULL) {
-       mvaddstr(y, x, def);
-       move(y, x);
-       use_def = TRUE;
-    }
-
-    refresh();
-    while ((c = getch()) != '\n' && c != CR) {
-       switch (c) {
-       case ESC:
-           move(y, x);
-           clrtoeol();
-           refresh();
-           return GS_ESCAPE;
-       case DEL:
-       case '\b':
-           if (i > 0) {
-               str[--i] = 0;
-               mvaddch(y, x+i, ' ');
-               move(y, x+i);
-           } else if (use_def) {
-               clrtoeol();
-               use_def = FALSE;
-           } else
-               putchar(BELL);
-           break;
-       default:
-           if (i < len && isprint(c)) {
-               mvaddch(y, x+i, c);
-               if (use_def) {
-                   clrtoeol();
-                   use_def = FALSE;
-               }
-               str[i++] = c;
-               str[i] = 0;
-           } else
-               putchar(BELL);
-       }
-       refresh();
-    }
-
-    if (use_def)
-       return GS_DEFAULT;
-    else
-       return i;
-}
-
-void clear_warning(void)
-{
-    int i;
-
-    if (!warning_last_time)
-       return;
-
-    move(WARNING_START,0);
-    for (i = 0; i < COLS; i++)
-       addch(' ');
-
-    warning_last_time = FALSE;
-}
-
-void print_warning(char *s)
-{
-    mvaddstr(WARNING_START, (COLS-strlen(s))/2, s);
-    putchar(BELL); /* CTRL-G */
-
-    warning_last_time = TRUE;
-}
-
-void fatal(char *s)
-{
-    char str[LINE_LENGTH];
-
-    sprintf(str, "FATAL ERROR: %s", s);
-    mvaddstr(WARNING_START, (COLS-strlen(str))/2, str);
-    sprintf(str, "Press any key to exit fdisk");
-    mvaddstr(WARNING_START+1, (COLS-strlen(str))/2, str);
-    putchar(BELL); /* CTRL-G */
-
-    refresh();
-
-    (void)getch();
-
-    signal(SIGINT, old_SIGINT);
-    signal(SIGTERM, old_SIGTERM);
-    mvcur(0, COLS-1, LINES-1, 0);
-    nl();
-    endwin();
-    fdexit(1);
-}
-
-void read_sector(char *buffer, int sect_num)
-{
-    if (ext2_llseek(fd, sect_num*SECTOR_SIZE, SEEK_SET) < 0)
-       fatal(BAD_SEEK);
-    if (read(fd, buffer, SECTOR_SIZE) != SECTOR_SIZE)
-       fatal(BAD_READ);
-}
-
-void write_sector(char *buffer, int sect_num)
-{
-    if (ext2_llseek(fd, sect_num*SECTOR_SIZE, SEEK_SET) < 0)
-       fatal(BAD_SEEK);
-    if (write(fd, buffer, SECTOR_SIZE) != SECTOR_SIZE)
-       fatal(BAD_WRITE);
-}
-
-void check_part_info(void)
-{
-    int i, pri = 0, log = 0;
-
-    for (i = 0; i < num_parts; i++)
-       if (p_info[i].id > 0 && IS_PRIMARY(p_info[i].num))
-           pri++;
-       else if (p_info[i].id > 0 && IS_LOGICAL(p_info[i].num))
-           log++;
-    if (ext_info.id == EXTENDED)
-       if (log > 0)
-           pri++;
-       else {
-           ext_info.first_sector = 0;
-           ext_info.last_sector = 0;
-           ext_info.offset = 0;
-           ext_info.flags = 0;
-           ext_info.id = FREE_SPACE;
-           ext_info.num = PRIMARY;
-       }
-
-    if (pri >= 4)
-       for (i = 0; i < num_parts; i++)
-           if (p_info[i].id == FREE_SPACE || p_info[i].id == UNUSABLE)
-               if (ext_info.id == EXTENDED)
-                   if (p_info[i].first_sector >= ext_info.first_sector &&
-                       p_info[i].last_sector <= ext_info.last_sector) {
-                       p_info[i].id = FREE_SPACE;
-                       p_info[i].num = LOGICAL;
-                   } else if (i > 0 &&
-                              p_info[i-1].first_sector >=
-                              ext_info.first_sector &&
-                              p_info[i-1].last_sector <=
-                              ext_info.last_sector) {
-                       p_info[i].id = FREE_SPACE;
-                       p_info[i].num = LOGICAL;
-                   } else if (i < num_parts-1 &&
-                              p_info[i+1].first_sector >=
-                              ext_info.first_sector &&
-                              p_info[i+1].last_sector <=
-                              ext_info.last_sector) {
-                       p_info[i].id = FREE_SPACE;
-                       p_info[i].num = LOGICAL;
-                   } else
-                       p_info[i].id = UNUSABLE;
-               else /* if (ext_info.id != EXTENDED) */
-                   p_info[i].id = UNUSABLE;
-           else /* if (p_info[i].id > 0) */
-               while (0); /* Leave these alone */
-    else /* if (pri < 4) */
-       for (i = 0; i < num_parts; i++) {
-           if (p_info[i].id == UNUSABLE)
-               p_info[i].id = FREE_SPACE;
-           if (p_info[i].id == FREE_SPACE)
-               if (ext_info.id == EXTENDED)
-                   if (p_info[i].first_sector >= ext_info.first_sector &&
-                       p_info[i].last_sector <= ext_info.last_sector)
-                       p_info[i].num = LOGICAL;
-                   else if (i > 0 &&
-                            p_info[i-1].first_sector >=
-                            ext_info.first_sector &&
-                            p_info[i-1].last_sector <=
-                            ext_info.last_sector)
-                       p_info[i].num = PRI_OR_LOG;
-                   else if (i < num_parts-1 &&
-                            p_info[i+1].first_sector >=
-                            ext_info.first_sector &&
-                            p_info[i+1].last_sector <=
-                            ext_info.last_sector)
-                       p_info[i].num = PRI_OR_LOG;
-                   else
-                       p_info[i].num = PRIMARY;
-               else /* if (ext_info.id != EXTENDED) */
-                   p_info[i].num = PRI_OR_LOG;
-           else /* if (p_info[i].id > 0) */
-               while (0); /* Leave these alone */
-       }
-}
-
-void remove_part(int i)
-{
-    int p;
-
-    for (p = i; p < num_parts; p++)
-       p_info[p] = p_info[p+1];
-
-    num_parts--;
-}
-
-void insert_part(int i, int num, int id, int flags, int first, int last,
-                int offset)
-{
-    int p;
-
-    for (p = num_parts; p > i; p--)
-        p_info[p] = p_info[p-1];
-
-    p_info[i].first_sector = first;
-    p_info[i].last_sector = last;
-    p_info[i].offset = offset;
-    p_info[i].flags = flags;
-    p_info[i].id = id;
-    p_info[i].num = num;
-
-    num_parts++;
-}
-
-void del_part(int i)
-{
-    int num = p_info[i].num;
-
-    if (i > 0 && (p_info[i-1].id == FREE_SPACE ||
-                 p_info[i-1].id == UNUSABLE)) {
-       /* Merge with previous partition */
-       p_info[i-1].last_sector = p_info[i].last_sector;
-       remove_part(i--);
-    }
-
-    if (i < num_parts - 1 && (p_info[i+1].id == FREE_SPACE ||
-                             p_info[i+1].id == UNUSABLE)) {
-       /* Merge with next partition */
-       p_info[i+1].first_sector = p_info[i].first_sector;
-       remove_part(i);
-    }
-
-    if (i > 0)
-       p_info[i].first_sector = p_info[i-1].last_sector + 1;
-    else
-       p_info[i].first_sector = 0;
-
-    if (i < num_parts - 1)
-       p_info[i].last_sector = p_info[i+1].first_sector - 1;
-    else
-       p_info[i].last_sector = sectors*heads*cylinders - 1;
-
-    p_info[i].offset = 0;
-    p_info[i].flags = 0;
-    p_info[i].id = FREE_SPACE;
-    p_info[i].num = PRI_OR_LOG;
-
-    if (IS_LOGICAL(num)) {
-       /* We have a logical partition --> shrink the extended partition
-        * if (1) this is the first logical drive, or (2) this is the
-        * last logical drive; and if there are any other logical drives
-        * then renumber the ones after "num".
-        */
-       if (i == 0 || (i > 0 && IS_PRIMARY(p_info[i-1].num)))
-           ext_info.first_sector = p_info[i].last_sector + 1;
-       if (i == num_parts-1 ||
-           (i < num_parts-1 && IS_PRIMARY(p_info[i+1].num)))
-           ext_info.last_sector = p_info[i].first_sector - 1;
-       for (i = 0; i < num_parts; i++)
-           if (p_info[i].num > num)
-               p_info[i].num--;
-    }
-
-    /* Clean up the rest of the partitions */
-    check_part_info();
-}
-
-int add_part(int num, int id, int flags, int first, int last, int offset)
-{
-    int i, pri = 0, log = 0;
-
-    if (num_parts == MAXIMUM_PARTS ||
-       first < 0 ||
-       first >= cylinders*heads*sectors ||
-       last < 0 ||
-       last >= cylinders*heads*sectors)
-       return -1;
-
-    for (i = 0; i < num_parts; i++)
-       if (p_info[i].id > 0 && IS_PRIMARY(p_info[i].num))
-           pri++;
-       else if (p_info[i].id > 0 && IS_LOGICAL(p_info[i].num))
-           log++;
-    if (ext_info.id == EXTENDED && log > 0)
-       pri++;
-
-    if (IS_PRIMARY(num))
-       if (pri >= 4)
-           return -1;
-       else
-           pri++;
-
-    for (i = 0; p_info[i].last_sector < first; i++);
-
-    if (p_info[i].id != FREE_SPACE || last > p_info[i].last_sector)
-       return -1;
-
-    if (id == EXTENDED)
-       if (ext_info.id != FREE_SPACE)
-           return -1;
-       else if (IS_PRIMARY(num)) {
-           ext_info.first_sector = first;
-           ext_info.last_sector = last;
-           ext_info.offset = offset;
-           ext_info.flags = flags;
-           ext_info.id = EXTENDED;
-           ext_info.num = num;
-
-           return 0;
-       } else
-           return -1;
-
-    if (IS_LOGICAL(num)) {
-       if (ext_info.id != EXTENDED) {
-           print_warning("!!!! Internal error creating logical "
-                         "drive with no extended partition !!!!");
-       } else {
-           /* We might have a logical partition outside of the extended
-            * partition's range --> we have to extend the extended
-            * partition's range to encompass this new partition, but we
-            * must make sure that there are no primary partitions between
-            * it and the closest logical drive in extended partition.
-            */
-           if (first < ext_info.first_sector) {
-               if (i < num_parts-1 && IS_PRIMARY(p_info[i+1].num)) {
-                   print_warning(TWO_EXTENDEDS);
-                   return -1;
-               } else {
-                   if (first == 0) {
-                       ext_info.first_sector = 0;
-                       ext_info.offset = first = offset;
-                   } else
-                       ext_info.first_sector = first;
-               }
-           } else if (last > ext_info.last_sector) {
-               if (i > 0 && IS_PRIMARY(p_info[i-1].num)) {
-                   print_warning(TWO_EXTENDEDS);
-                   return -1;
-               } else
-                   ext_info.last_sector = last;
-           }
-       }
-    }
-
-    if (first != p_info[i].first_sector &&
-       !(IS_LOGICAL(num) && first == offset)) {
-       insert_part(i, PRI_OR_LOG, FREE_SPACE, 0,
-                   p_info[i].first_sector, first-1, 0);
-       i++;
-    }
-
-    if (last != p_info[i].last_sector)
-       insert_part(i+1, PRI_OR_LOG, FREE_SPACE, 0,
-                   last+1, p_info[i].last_sector, 0);
-
-    p_info[i].first_sector = first;
-    p_info[i].last_sector = last;
-    p_info[i].offset = offset;
-    p_info[i].flags = flags;
-    p_info[i].id = id;
-    p_info[i].num = num;
-
-    check_part_info();
-
-    return 0;
-}
-
-int find_primary(void)
-{
-    int num = 0, cur = 0;
-
-    while (cur < num_parts && IS_PRIMARY(num))
-       if ((p_info[cur].id > 0 && p_info[cur].num == num) ||
-           (ext_info.id == EXTENDED && ext_info.num == num)) {
-           num++;
-           cur = 0;
-       } else
-           cur++;
-
-    if (!IS_PRIMARY(num))
-       return -1;
-    else
-       return num;
-}
-
-int find_logical(int i)
-{
-    int num = -1;
-    int j;
-
-    for (j = i; j < num_parts && num == -1; j++)
-       if (p_info[j].id > 0 && IS_LOGICAL(p_info[j].num))
-           num = p_info[j].num;
-
-    if (num == -1) {
-       num = 4;
-       for (j = 0; j < num_parts; j++)
-           if (p_info[j].id > 0 && p_info[j].num == num)
-               num++;
-    }
-
-    return num;
-}
-
-void inc_logical(int i)
-{
-    int j;
-
-    for (j = i; j < num_parts; j++)
-       if (p_info[j].id > 0 && IS_LOGICAL(p_info[j].num))
-           p_info[j].num++;
-}
-
-void new_part(int i)
-{
-    char response[LINE_LENGTH], def[LINE_LENGTH];
-    char c;
-    int first = p_info[i].first_sector;
-    int last = p_info[i].last_sector;
-    int offset = 0;
-    int flags = 0;
-    int id = LINUX;
-    int num = -1;
-    int num_sects = last - first + 1;
-    int len, ext, j;
-
-    if (p_info[i].num == PRI_OR_LOG) {
-       mvaddstr(COMMAND_LINE_Y, COMMAND_LINE_X, "Primary or logical [pl]: ");
-       clrtoeol();
-       refresh();
-       while (toupper(c = getch()) != 'P' && toupper(c) != 'L' && c != ESC);
-       if (toupper(c) == 'P')
-           num = find_primary();
-       else if (toupper(c) == 'L')
-           num = find_logical(i);
-       else
-           return;
-    } else if (p_info[i].num == PRIMARY)
-       num = find_primary();
-    else if (p_info[i].num == LOGICAL)
-       num = find_logical(i);
-    else
-       print_warning("!!! Internal error !!!");
-
-    sprintf(def, "%.2f", ceiling(num_sects/20.48)/100);
-    mvaddstr(COMMAND_LINE_Y, COMMAND_LINE_X, "Size (in MB): ");
-    if ((len = get_string(response, LINE_LENGTH, def)) <= 0 &&
-       len != GS_DEFAULT)
-       return;
-    else if (len > 0) {
-#define num_cyls(bytes) (round_int(bytes/SECTOR_SIZE/(sectors*heads)))
-       for (j = 0;
-            j < len-1 && (isdigit(response[j]) || response[j] == '.');
-            j++);
-       if (toupper(response[j]) == 'K') {
-           num_sects = num_cyls(atof(response)*1024)*sectors*heads;
-       } else if (toupper(response[j]) == 'M') {
-           num_sects = num_cyls(atof(response)*1024*1024)*sectors*heads;
-       } else if (toupper(response[j]) == 'C') {
-           num_sects = round_int(atof(response))*sectors*heads;
-       } else if (toupper(response[j]) == 'S') {
-           num_sects = round_int(atof(response));
-       } else {
-           num_sects = num_cyls(atof(response)*1024*1024)*sectors*heads;
-       }
-    }
-
-    if (num_sects <= 0 ||
-       num_sects > p_info[i].last_sector - p_info[i].first_sector + 1)
-       return;
-
-    if (num_sects < p_info[i].last_sector - p_info[i].first_sector + 1) {
-       /* Determine where inside free space to put partition.
-        */
-       mvaddstr(COMMAND_LINE_Y, COMMAND_LINE_X,
-                "Add partition at beginning or end of free space [be]: ");
-       clrtoeol();
-       refresh();
-       while (toupper(c = getch()) != 'B' && toupper(c) != 'E' && c != ESC);
-       if (toupper(c) == 'B')
-           last = first + num_sects - 1;
-       else if (toupper(c) == 'E')
-           first = last - num_sects + 1;
-       else
-           return;
-    }
-
-    if (IS_LOGICAL(num) && ext_info.id != EXTENDED) {
-       /* We want to add a logical partition, but need to create an
-        * extended partition first.
-        */
-       if ((ext = find_primary()) < 0) {
-           print_warning(NEED_EXT);
-           return;
-       }
-       (void)add_part(ext, EXTENDED, 0, first, last,
-                      (first == 0 ? sectors : 0));
-    }
-
-    if (IS_LOGICAL(num))
-       inc_logical(i);
-
-    /* Now we have a complete partition to ourselves */
-    if (first == 0 || IS_LOGICAL(num))
-       offset = sectors;
-
-    (void)add_part(num, id, flags, first, last, offset);
-}
-
-void clear_p_info(void)
-{
-    num_parts = 1;
-    p_info[0].first_sector = 0;
-    p_info[0].last_sector = sectors*heads*cylinders - 1;
-    p_info[0].offset = 0;
-    p_info[0].flags = 0;
-    p_info[0].id = FREE_SPACE;
-    p_info[0].num = PRI_OR_LOG;
-
-    ext_info.first_sector = 0;
-    ext_info.last_sector = 0;
-    ext_info.offset = 0;
-    ext_info.flags = 0;
-    ext_info.id = FREE_SPACE;
-    ext_info.num = PRIMARY;
-}
-
-void fill_p_info(void)
-{
-    int p, i;
-    struct hd_geometry geometry;
-    partition_table buffer;
-    partition_info tmp_ext = { 0, 0, 0, 0, FREE_SPACE, PRIMARY };
-
-    if ((fd = open(disk_device, O_RDWR)) < 0)
-       fatal(BAD_OPEN);
-    read_sector(buffer.c.b, 0);
-
-    if (!ioctl(fd, HDIO_GETGEO, &geometry)) {
-       if (!heads)
-           heads = geometry.heads;
-       if (!sectors)
-           sectors = geometry.sectors;
-       if (!cylinders)
-           cylinders = geometry.cylinders;
-    }
-
-    if (!heads || !sectors || !cylinders)
-       fatal(BAD_GEOMETRY);
-
-    clear_p_info();
-
-    if (!zero_table) {
-       for (i = 0; i < 4; i++) {
-           if (buffer.p.part[i].sys_ind > 0 &&
-               add_part(i,
-                        buffer.p.part[i].sys_ind,
-                        buffer.p.part[i].boot_ind,
-                        ((buffer.p.part[i].start_sect <= sectors) ?
-                         0 : buffer.p.part[i].start_sect),
-                        buffer.p.part[i].start_sect +
-                        buffer.p.part[i].nr_sects - 1,
-                        ((buffer.p.part[i].start_sect <= sectors) ?
-                         buffer.p.part[i].start_sect : 0))) {
-               fatal(BAD_PRIMARY);
-           }
-           if (buffer.p.part[i].sys_ind == EXTENDED)
-               tmp_ext = ext_info;
-       }
-
-       if (tmp_ext.id == EXTENDED) {
-           ext_info = tmp_ext;
-           logical_sectors[logical] = ext_info.first_sector;
-           read_sector(buffer.c.b, logical_sectors[logical++]);
-           i = 4;
-           do {
-               for (p = 0;
-                    p < 4 && (!buffer.p.part[p].sys_ind ||
-                              buffer.p.part[p].sys_ind == 5);
-                    p++);
-               if (p > 3)
-                   fatal(BAD_LOGICAL);
-
-               if (add_part(i++,
-                            buffer.p.part[p].sys_ind,
-                            buffer.p.part[p].boot_ind,
-                            logical_sectors[logical-1],
-                            logical_sectors[logical-1] +
-                            buffer.p.part[p].start_sect +
-                            buffer.p.part[p].nr_sects - 1,
-                            buffer.p.part[p].start_sect)) {
-                   fatal(BAD_LOGICAL);
-               }
-
-               for (p = 0;
-                    p < 4 && buffer.p.part[p].sys_ind != 5;
-                    p++);
-               if (p < 4) {
-                   logical_sectors[logical] =
-                       ext_info.first_sector + buffer.p.part[p].start_sect;
-                   read_sector(buffer.c.b, logical_sectors[logical++]);
-               }
-           } while (p < 4 && logical < MAXIMUM_PARTS-4);
-       }
-    }
-}
-
-void fill_part_table(struct partition *p, partition_info *pi)
-{
-    int sects;
-
-    p->boot_ind = pi->flags;
-    p->sys_ind = pi->id;
-    if (IS_LOGICAL(pi->num))
-       p->start_sect = pi->offset;
-    else
-       p->start_sect = pi->first_sector + pi->offset;
-    p->nr_sects = pi->last_sector - (pi->first_sector+pi->offset) + 1;
-    sects = (((pi->first_sector+pi->offset)/(sectors*heads) > 1023) ?
-            heads*sectors*1024 - 1 : pi->first_sector+pi->offset);
-    set_hsc(p->head, p->sector, p->cyl, sects);
-    sects = ((pi->last_sector/(sectors*heads) > 1023) ?
-            heads*sectors*1024 - 1 : pi->last_sector);
-    set_hsc(p->end_head, p->end_sector, p->end_cyl, sects);
-}
-
-void fill_primary_table(partition_table *buffer)
-{
-    int i;
-
-    /* Zero out existing table */
-    for (i = 0x1BE; i < SECTOR_SIZE; i++)
-       buffer->c.b[i] = 0;
-
-    for (i = 0; i < num_parts; i++)
-       if (IS_PRIMARY(p_info[i].num))
-           fill_part_table(&(buffer->p.part[p_info[i].num]), &(p_info[i]));
-
-    if (ext_info.id == EXTENDED)
-       fill_part_table(&(buffer->p.part[ext_info.num]), &ext_info);
-
-    buffer->p.flag = PART_TABLE_FLAG;
-}
-
-void fill_logical_table(partition_table *buffer, partition_info *pi)
-{
-    struct partition *p;
-    int i, sects;
-
-    for (i = 0; i < logical && pi->first_sector != logical_sectors[i]; i++);
-    if (i == logical || buffer->p.flag != (unsigned short)PART_TABLE_FLAG)
-       for (i = 0; i < SECTOR_SIZE; i++)
-           buffer->c.b[i] = 0;
-
-    /* Zero out existing table */
-    for (i = 0x1BE; i < SECTOR_SIZE; i++)
-       buffer->c.b[i] = 0;
-
-    fill_part_table(&(buffer->p.part[0]), pi);
-
-    for (i = 0;
-        i < num_parts && pi->num != p_info[i].num - 1;
-        i++);
-
-    if (i < num_parts) {
-       p = &(buffer->p.part[1]);
-       pi = &(p_info[i]);
-
-       p->boot_ind = 0;
-       p->sys_ind = 5;
-       p->start_sect = pi->first_sector - ext_info.first_sector;
-       p->nr_sects = pi->last_sector - pi->first_sector + 1;
-       sects = ((pi->first_sector/(sectors*heads) > 1023) ?
-                heads*sectors*1024 - 1 : pi->first_sector);
-       set_hsc(p->head, p->sector, p->cyl, sects);
-       sects = ((pi->last_sector/(sectors*heads) > 1023) ?
-                heads*sectors*1024 - 1 : pi->last_sector);
-       set_hsc(p->end_head, p->end_sector, p->end_cyl, sects);
-    }
-
-    buffer->p.flag = PART_TABLE_FLAG;
-}
-
-void write_part_table(void)
-{
-    int i, done = FALSE, len;
-    partition_table buffer;
-    char response[LINE_LENGTH];
-
-    print_warning(WRITE_WARN);
-
-    while (!done) {
-       mvaddstr(COMMAND_LINE_Y, COMMAND_LINE_X,
-                "Are you sure you want write the partition table to disk? (yes or no): ");
-       
-       len = get_string(response, LINE_LENGTH, NULL);
-
-       clear_warning();
-
-       if (len == GS_ESCAPE)
-           return;
-       else if (len == 2 &&
-                toupper(response[0]) == 'N' &&
-                toupper(response[1]) == 'O') {
-           print_warning(NO_WRITE);
-           return;
-       } else if (len == 3 &&
-                  toupper(response[0]) == 'Y' &&
-                  toupper(response[1]) == 'E' &&
-                  toupper(response[2]) == 'S')
-           done = TRUE;
-       else
-           print_warning(YES_NO);
-    }
-
-    clear_warning();
-    print_warning(WRITING_PART);
-    refresh();
-    
-    read_sector(buffer.c.b, 0);
-    fill_primary_table(&buffer);
-    write_sector(buffer.c.b, 0);
-
-    for (i = 0; i < num_parts; i++)
-       if (IS_LOGICAL(p_info[i].num)) {
-           /* Read the extended partition table from disk ??? KEM */
-           read_sector(buffer.c.b, p_info[i].first_sector);
-           fill_logical_table(&buffer, &(p_info[i]));
-           write_sector(buffer.c.b, p_info[i].first_sector);
-       }
-
-    sync();
-    sleep(2);
-    if (!ioctl(fd,BLKRRPART))
-       changed = TRUE;
-    sync();
-    sleep(4);
-
-    clear_warning();
-    if (changed)
-       print_warning(YES_WRITE);
-    else
-       print_warning(RRPART_FAILED);
-}
-
-void fp_printf(FILE *fp, char *format, ...)
-{
-    va_list args;
-    char buf[1024];
-    int y, x;
-
-    va_start(args, format);
-    vsprintf(buf, format, args);
-    va_end(args);
-
-    if (fp == NULL) {
-       /* The following works best if the string to be printed has at
-           most only one newline. */
-       printw("%s", buf);
-       getyx(stdscr, y, x);
-       if (y >= COMMAND_LINE_Y-2) {
-           mvaddstr(COMMAND_LINE_Y, COMMAND_LINE_X,
-                    "Press any key to continue...");
-           clrtoeol();
-           refresh();
-           (void)getch();
-           erase();
-           move(0, 0);
-       }
-    } else
-       fprintf(fp, "%s", buf);
-}
-
-#define MAX_PER_LINE 16
-void print_file_buffer(FILE *fp, char *buffer)
-{
-    int i,l;
-
-    for (i = 0, l = 0; i < SECTOR_SIZE; i++, l++) {
-       if (l == 0)
-           fp_printf(fp, "0x%03X:", i);
-       fp_printf(fp, " %02X", (unsigned char) buffer[i]);
-       if (l == MAX_PER_LINE - 1) {
-           fp_printf(fp, "\n");
-           l = -1;
-       }
-    }
-    if (l > 0)
-       fp_printf(fp, "\n");
-    fp_printf(fp, "\n");
-}
-
-void print_raw_table(void)
-{
-    int i, to_file;
-    partition_table buffer;
-    char fname[LINE_LENGTH];
-    FILE *fp;
-
-    if (print_only) {
-       fp = stdout;
-       to_file = TRUE;
-    } else {
-       mvaddstr(COMMAND_LINE_Y, COMMAND_LINE_X,
-                "Enter filename or press RETURN to display on screen: ");
-
-       if ((to_file = get_string(fname, LINE_LENGTH, NULL)) < 0)
-           return;
-
-       if (to_file) {
-           if ((fp = fopen(fname, "w")) == NULL) {
-               char errstr[LINE_LENGTH];
-               sprintf(errstr, PRINT_OPEN_ERR, fname);
-               print_warning(errstr);
-               return;
-           }
-       } else {
-           fp = NULL;
-           erase();
-           move(0, 0);
-       }
-    }
-
-    fp_printf(fp, "Disk Drive: %s\n", disk_device);
-
-    read_sector(buffer.c.b, 0);
-    fill_primary_table(&buffer);
-    print_file_buffer(fp, buffer.c.b);
-
-    for (i = 0; i < num_parts; i++)
-       if (IS_LOGICAL(p_info[i].num)) {
-           read_sector(buffer.c.b, p_info[i].first_sector);
-           fill_logical_table(&buffer, &(p_info[i]));
-           print_file_buffer(fp, buffer.c.b);
-       }
-
-    if (to_file) {
-       if (!print_only)
-           fclose(fp);
-    } else {
-       mvaddstr(COMMAND_LINE_Y, COMMAND_LINE_X,
-                "Press any key to continue...");
-       clrtoeol();
-       refresh();
-       (void)getch();
-    }
-}
-
-void print_p_info_entry(FILE *fp, partition_info *p)
-{
-    int size;
-    char part_str[21];
-
-    if (p->id == UNUSABLE)
-       fp_printf(fp, "   None   ");
-    else if (p->id == FREE_SPACE && p->num == PRI_OR_LOG)
-       fp_printf(fp, "   Pri/Log");
-    else if (p->id == FREE_SPACE && p->num == PRIMARY)
-       fp_printf(fp, "   Primary");
-    else if (p->id == FREE_SPACE && p->num == LOGICAL)
-       fp_printf(fp, "   Logical");
-    else
-       fp_printf(fp, "%2d %-7.7s", p->num+1,
-                 IS_LOGICAL(p->num) ? "Logical" : "Primary");
-
-    fp_printf(fp, " ");
-
-    fp_printf(fp, "%7d%c", p->first_sector,
-             ((p->first_sector/(sectors*heads)) !=
-              ((float)p->first_sector/(sectors*heads)) ?
-              '*' : ' '));
-
-    fp_printf(fp, " ");
-
-    fp_printf(fp, "%7d%c", p->last_sector,
-             (((p->last_sector+1)/(sectors*heads)) !=
-              ((float)(p->last_sector+1)/(sectors*heads)) ?
-              '*' : ' '));
-
-    fp_printf(fp, " ");
-
-    fp_printf(fp, "%6d%c", p->offset,
-             ((((p->first_sector == 0 || IS_LOGICAL(p->num)) &&
-                (p->offset != sectors)) ||
-               (p->first_sector != 0 && IS_PRIMARY(p->num) &&
-                p->offset != 0)) ?
-              '#' : ' '));
-
-    fp_printf(fp, " ");
-
-    size = p->last_sector - p->first_sector + 1;
-    fp_printf(fp, "%7d%c", size,
-             ((size/(sectors*heads)) != ((float)size/(sectors*heads)) ?
-              '*' : ' '));
-
-    fp_printf(fp, " ");
-
-    if (p->id == UNUSABLE)
-       sprintf(part_str, "%.16s", "Unusable");
-    else if (p->id == FREE_SPACE)
-       sprintf(part_str, "%.16s", "Free Space");
-    else if (partition_type[p->id])
-       sprintf(part_str, "%.16s (%02X)", partition_type[p->id], p->id);
-    else
-       sprintf(part_str, "%.16s (%02X)", "Unknown", p->id);
-    fp_printf(fp, "%-21.21s", part_str);
-
-    fp_printf(fp, " ");
-
-    if (p->flags == ACTIVE_FLAG)
-       fp_printf(fp, "Boot (%02X)", p->flags);
-    else if (p->flags != 0)
-       fp_printf(fp, "Unknown (%02X)", p->flags);
-    else
-       fp_printf(fp, "None (%02X)", p->flags);
-
-    fp_printf(fp, "\n");
-}
-
-void print_p_info(void)
-{
-    char fname[LINE_LENGTH];
-    FILE *fp;
-    int i, to_file, pext = (ext_info.id == EXTENDED);
-
-    if (print_only) {
-       fp = stdout;
-       to_file = TRUE;
-    } else {
-       mvaddstr(COMMAND_LINE_Y, COMMAND_LINE_X,
-                "Enter filename or press RETURN to display on screen: ");
-
-       if ((to_file = get_string(fname, LINE_LENGTH, NULL)) < 0)
-           return;
-
-       if (to_file) {
-           if ((fp = fopen(fname, "w")) == NULL) {
-               char errstr[LINE_LENGTH];
-               sprintf(errstr, PRINT_OPEN_ERR, fname);
-               print_warning(errstr);
-               return;
-           }
-       } else {
-           fp = NULL;
-           erase();
-           move(0, 0);
-       }
-    }
-
-    fp_printf(fp, "Partition Table for %s\n", disk_device);
-    fp_printf(fp, "\n");
-    fp_printf(fp, "           First    Last\n");
-    fp_printf(fp, " # Type    Sector   Sector   Offset  Length   Filesystem Type (ID)  Flags\n");
-    fp_printf(fp, "-- ------- -------- -------- ------- -------- --------------------- ---------\n");
-
-    for (i = 0; i < num_parts; i++) {
-       if (pext && (p_info[i].first_sector >= ext_info.first_sector)) {
-           print_p_info_entry(fp,&ext_info);
-           pext = FALSE;
-       }
-       print_p_info_entry(fp, &(p_info[i]));
-    }
-
-    if (to_file) {
-       if (!print_only)
-           fclose(fp);
-    } else {
-       mvaddstr(COMMAND_LINE_Y, COMMAND_LINE_X,
-                "Press any key to continue...");
-       clrtoeol();
-       refresh();
-       (void)getch();
-    }
-}
-
-void print_part_entry(FILE *fp, int num, partition_info *pi)
-{
-    int first = 0, start = 0, end = 0, size = 0;
-    int ss = 0, sh = 0, sc = 0;
-    int es = 0, eh = 0, ec = 0;
-    int flags = 0, id = 0;
-
-    if (pi != NULL) {
-       flags = pi->flags;
-       id = pi->id;
-
-       if (IS_LOGICAL(num))
-           first = pi->offset;
-       else
-           first = pi->first_sector + pi->offset;
-
-       start = pi->first_sector + pi->offset;
-       end = pi->last_sector;
-       size = end - start + 1;
-       if ((start/(sectors*heads)) > 1023)
-           start = heads*sectors*1024 - 1;
-       if ((end/(sectors*heads)) > 1023)
-           end = heads*sectors*1024 - 1;
-
-       ss = start % sectors + 1;
-       start /= sectors;
-       sh = start % heads;
-       sc = start / heads;
-
-       es = end % sectors + 1;
-       end /= sectors;
-       eh = end % heads;
-       ec = end / heads;
-    }
-
-    fp_printf(fp, "%2d  0x%02X %4d %4d %4d 0x%02X %4d %4d %4d %7d %7d\n",
-             num+1, flags, sh, ss, sc, id, eh, es, ec, first, size);
-}
-
-
-void print_part_table(void)
-{
-    int i, j, to_file;
-    char fname[LINE_LENGTH];
-    FILE *fp;
-
-    if (print_only) {
-       fp = stdout;
-       to_file = TRUE;
-    } else {
-       mvaddstr(COMMAND_LINE_Y, COMMAND_LINE_X,
-                "Enter filename or press RETURN to display on screen: ");
-
-       if ((to_file = get_string(fname, LINE_LENGTH, NULL)) < 0)
-           return;
-
-       if (to_file) {
-           if ((fp = fopen(fname, "w")) == NULL) {
-               char errstr[LINE_LENGTH];
-               sprintf(errstr, PRINT_OPEN_ERR, fname);
-               print_warning(errstr);
-               return;
-           }
-       } else {
-           fp = NULL;
-           erase();
-           move(0, 0);
-       }
-    }
-
-    fp_printf(fp, "Partition Table for %s\n", disk_device);
-    fp_printf(fp, "\n");
-    fp_printf(fp, "         ---Starting---      ----Ending---- Start   Number\n");
-    fp_printf(fp, " # Flags Head Sect Cyl   ID  Head Sect Cyl  Sector  Sectors\n");
-    fp_printf(fp, "-- ----- ---- ---- ---- ---- ---- ---- ---- ------- -------\n");
-
-    for (i = 0; i < 4; i++) {
-       for (j = 0;
-            j < num_parts && (p_info[j].id <= 0 || p_info[j].num != i);
-            j++);
-       if (j < num_parts) {
-           print_part_entry(fp, i, &(p_info[j]));
-       } else if (ext_info.id == EXTENDED && ext_info.num == i) {
-           print_part_entry(fp, i, &ext_info);
-       } else {
-           print_part_entry(fp, i, NULL);
-       }
-    }
-
-    for (i = 0; i < num_parts; i++)
-       if (IS_LOGICAL(p_info[i].num))
-           print_part_entry(fp, p_info[i].num, &(p_info[i]));
-
-    if (to_file) {
-       if (!print_only)
-           fclose(fp);
-    } else {
-       mvaddstr(COMMAND_LINE_Y, COMMAND_LINE_X,
-                "Press any key to continue...");
-       clrtoeol();
-       refresh();
-       (void)getch();
-    }
-}
-
-void print_tables(void)
-{
-    int done = FALSE;
-
-    mvaddstr(COMMAND_LINE_Y, COMMAND_LINE_X, "Print format [rst]: ");
-    clrtoeol();
-    refresh();
-
-    while (!done)
-       switch (toupper(getch())) {
-       case 'R':
-           print_raw_table();
-           done = TRUE;
-           break;
-       case 'S':
-           print_p_info();
-           done = TRUE;
-           break;
-       case 'T':
-           print_part_table();
-           done = TRUE;
-           break;
-       case ESC:
-           done = TRUE;
-           break;
-       }
-}
-
-#define END_OF_HELP "EOHS!"
-#define NEW_HELP_SCREEN "SNHS!"
-void display_help()
-{
-    char *help_text[] = {
-       "Help Screen for cfdisk " VERSION,
-       "",
-       "This is cfdisk, a curses based disk partitioning programs, which",
-       "allows you to create, delete and modify partitions on your hard",
-       "disk drive.",
-       "",
-       "Copyright (C) 1994 Kevin E. Martin",
-       "",
-       "Command      Meaning",
-       "-------      -------",
-       "  b          Toggle bootable flag of the current partition",
-       "  d          Delete the current partition",
-       "  g          Change cylinders, heads, sectors-per-track parameters",
-       "             WARNING: This option should only be used by people who",
-       "             know what they are doing.",
-       "  h          Print this screen",
-       "  m          Maximize disk usage of the current partition",
-       "             Note: This may make the partition incompatible with",
-       "             DOS, OS/2, ...",
-       "  n          Create new partition from free space",
-       "  p          Print partition table to the screen or to a file",
-       "             There are several different formats for the partition",
-       "             that you can choose from:",
-       "                r - Raw data (exactly what would be written to disk)",
-       "                s - Table ordered by sectors",
-       "                t - Table in raw format",
-       "  q          Quit program without writing partition table",
-       "  t          Change the filesystem type",
-       "  u          Change units of the partition size display",
-       "             Rotates through Mb, sectors and cylinders",
-       "  W          Write partition table to disk (must enter upper case W)",
-        "             Since this might destroy data on the disk, you must",
-       "             either confirm or deny the write by entering `yes' or",
-       "             `no'",
-       "Up Arrow     Move cursor to the previous partition",
-       "Down Arrow   Move cursor to the next partition",
-       "CTRL-L       Redraws the screen",
-       "  ?          Print this screen",
-       "",
-       "Note: All of the commands can be entered with either upper or lower",
-       "case letters (except for Writes).",
-       END_OF_HELP
-    };
-
-    int cur_line = 0;
-    FILE *fp = NULL;
-
-    erase();
-    move(0, 0);
-    while (strcmp(help_text[cur_line], END_OF_HELP))
-       if (!strcmp(help_text[cur_line], NEW_HELP_SCREEN)) {
-           mvaddstr(COMMAND_LINE_Y, COMMAND_LINE_X,
-                    "Press any key to continue...");
-           clrtoeol();
-           refresh();
-           (void)getch();
-           erase();
-           move(0, 0);
-           cur_line++;
-       } else
-           fp_printf(fp, "%s\n", help_text[cur_line++]);
-
-    mvaddstr(COMMAND_LINE_Y, COMMAND_LINE_X,
-            "Press any key to continue...");
-    clrtoeol();
-    refresh();
-    (void)getch();
-}
-
-int change_geometry(void)
-{
-    int ret_val = FALSE;
-    int done = FALSE;
-    char def[LINE_LENGTH];
-    char response[LINE_LENGTH];
-    int tmp_val;
-
-    while (!done) {
-       mvaddstr(COMMAND_LINE_Y, COMMAND_LINE_X,
-                "Change disk geometry information [chs]: ");
-       clrtoeol();
-       refresh();
-
-       clear_warning();
-
-       switch (toupper(getch())) {
-       case 'C':
-           sprintf(def, "%d", cylinders);
-           mvaddstr(COMMAND_LINE_Y, COMMAND_LINE_X,
-                    "Enter the number of cylinders: ");
-           if (get_string(response, LINE_LENGTH, def) > 0) {
-               tmp_val = atoi(response);
-               if (tmp_val > 0 && tmp_val <= MAX_CYLINDERS) {
-                   cylinders = tmp_val;
-                   ret_val = TRUE;
-               } else
-                   print_warning(BAD_CYLINDERS);
-           }
-           break;
-       case 'H':
-           sprintf(def, "%d", heads);
-           mvaddstr(COMMAND_LINE_Y, COMMAND_LINE_X,
-                    "Enter the number of heads: ");
-           if (get_string(response, LINE_LENGTH, def) > 0) {
-               tmp_val = atoi(response);
-               if (tmp_val > 0 && tmp_val <= MAX_HEADS) {
-                   heads = tmp_val;
-                   ret_val = TRUE;
-               } else
-                   print_warning(BAD_HEADS);
-           }
-           break;
-       case 'S':
-           sprintf(def, "%d", sectors);
-           mvaddstr(COMMAND_LINE_Y, COMMAND_LINE_X,
-                    "Enter the number of sectors per track: ");
-           if (get_string(response, LINE_LENGTH, def) > 0) {
-               tmp_val = atoi(response);
-               if (tmp_val > 0 && tmp_val <= MAX_SECTORS) {
-                   sectors = tmp_val;
-                   ret_val = TRUE;
-               } else
-                   print_warning(BAD_SECTORS);
-           }
-           break;
-       case ESC:
-       case CR:
-           done = TRUE;
-           break;
-       default:
-           putchar(BELL);
-           break;
-       }
-    }
-
-    if (ret_val) {
-       if (p_info[num_parts-1].last_sector > heads*sectors*cylinders-1) {
-           while (p_info[num_parts-1].first_sector > heads*sectors*cylinders-1) {
-               if (p_info[num_parts-1].id == FREE_SPACE ||
-                   p_info[num_parts-1].id == UNUSABLE)
-                   remove_part(num_parts-1);
-               else
-                   del_part(num_parts-1);
-           }
-
-           p_info[num_parts-1].last_sector = heads*sectors*cylinders - 1;
-
-           if (ext_info.last_sector > heads*sectors*cylinders-1)
-               ext_info.last_sector = heads*sectors*cylinders - 1;
-       } else if (p_info[num_parts-1].last_sector < heads*sectors*cylinders-1) {
-           if (p_info[num_parts-1].id == FREE_SPACE ||
-               p_info[num_parts-1].id == UNUSABLE) {
-               p_info[num_parts-1].last_sector = heads*sectors*cylinders - 1;
-           } else {
-               insert_part(num_parts, PRI_OR_LOG, FREE_SPACE, 0,
-                           p_info[num_parts-1].last_sector+1,
-                           heads*sectors*cylinders-1, 0);
-           }
-       }
-
-       /* Make sure the partitions are correct */
-       check_part_info();
-    }
-
-    return ret_val;
-}
-
-void change_id(int i)
-{
-    char id[LINE_LENGTH], def[LINE_LENGTH];
-    int num_types = 0;
-    int num_across, num_down;
-    int len, new_id = LINUX;
-    int y_start, y_end;
-    int j, pos;
-
-    for (num_types = 0, j = 1; j < NUM_PART_TYPES; j++)
-       if (partition_type[j])
-           num_types++;
-
-    num_across = COLS/COL_ID_WIDTH;
-    num_down = (((float)num_types)/num_across + 1);
-    y_start = COMMAND_LINE_Y - 1 - num_down;
-    if (y_start > DISK_TABLE_START+cur_part+4)
-       y_start = DISK_TABLE_START+cur_part+4;
-    y_end = y_start + num_down - 1;
-
-    for (j = y_start - 1; j <= y_end + 1; j++) {
-       move(j, 0);
-       clrtoeol();
-    }
-
-    for (pos = 0, j = 1; j < NUM_PART_TYPES; j++)
-       if (partition_type[j]) {
-           move(y_start + pos % num_down, (pos/num_down)*COL_ID_WIDTH + 1);
-           printw("%02X %-16.16s", j, partition_type[j]);
-           pos++;
-       }
-
-    sprintf(def, "%02X", new_id);
-    mvaddstr(COMMAND_LINE_Y, COMMAND_LINE_X, "Enter filesystem type: ");
-    if ((len = get_string(id, 2, def)) <= 0 && len != GS_DEFAULT)
-       return;
-
-    if (len != GS_DEFAULT) {
-       if (!isxdigit(id[0]))
-           return;
-       new_id = (isdigit(id[0]) ? id[0] - '0' : tolower(id[0]) - 'a' + 10);
-       if (len == 2)
-           if (isxdigit(id[1]))
-               new_id = new_id*16 +
-                   (isdigit(id[1]) ? id[1] - '0' : tolower(id[1]) - 'a' + 10);
-           else
-               return;
-    }
-
-    if (new_id == 0)
-       print_warning(ID_EMPTY);
-    else if (new_id == EXTENDED)
-       print_warning(ID_EXT);
-    else
-       p_info[i].id = new_id;
-}
-
-void draw_partition(int i)
-{
-    int size, j;
-    int y = i + DISK_TABLE_START + 2 - (cur_part/NUM_ON_SCREEN)*NUM_ON_SCREEN;
-
-    if (!arrow_cursor) {
-       move(y, 0);
-       for (j = 0; j < COLS; j++)
-           addch(' ');
-    }
-
-    if (p_info[i].id > 0) {
-       mvprintw(y, NAME_START,
-                "%s%d", disk_device, p_info[i].num+1);
-       if (p_info[i].flags) {
-           if (p_info[i].flags == ACTIVE_FLAG)
-               mvaddstr(y, FLAGS_START, "Boot");
-           else
-               mvprintw(y, FLAGS_START, "Unk(%02X)", p_info[i].flags);
-           if (p_info[i].first_sector == 0 || IS_LOGICAL(p_info[i].num)) {
-               if (p_info[i].offset != sectors)
-                   addstr(", NC");
-           } else {
-               if (p_info[i].offset != 0)
-                   addstr(", NC");
-           }
-       } else {
-           if (p_info[i].first_sector == 0 || IS_LOGICAL(p_info[i].num)) {
-               if (p_info[i].offset != sectors)
-                   mvaddstr(y, FLAGS_START, "NC");
-           } else {
-               if (p_info[i].offset != 0)
-                   mvaddstr(y, FLAGS_START, "NC");
-           }
-       }
-    }
-    mvaddstr(y, PTYPE_START,
-            (p_info[i].id == UNUSABLE ? "" :
-             (IS_LOGICAL(p_info[i].num) ? "Logical" :
-              (p_info[i].num >= 0 ? "Primary" :
-               (p_info[i].num == PRI_OR_LOG ? "Pri/Log" :
-                (p_info[i].num == PRIMARY ? "Primary" : "Logical"))))));
-    if (p_info[i].id == UNUSABLE)
-       mvaddstr(y, FSTYPE_START, "Unusable");
-    else if (p_info[i].id == FREE_SPACE)
-       mvaddstr(y, FSTYPE_START, "Free Space");
-    else if (partition_type[p_info[i].id])
-       mvaddstr(y, FSTYPE_START, partition_type[p_info[i].id]);
-    else
-       mvprintw(y, FSTYPE_START, "Unknown (%02X)", p_info[i].id);
-
-    size = p_info[i].last_sector - p_info[i].first_sector + 1;
-    if (display_units == SECTORS)
-       mvprintw(y, SIZE_START, "%9d", size);
-    else if (display_units == CYLINDERS)
-       mvprintw(y, SIZE_START, "%9d", size/(sectors*heads));
-    else
-       mvprintw(y, SIZE_START, "%9.2f", ceiling(size/20.48)/100);
-    if (((size/(sectors*heads)) != ceiling(size/(sectors*(float)heads))) ||
-       ((p_info[i].first_sector/(sectors*heads)) !=
-        ceiling(p_info[i].first_sector/(sectors*heads))))
-       mvprintw(y, COLUMNS-1, "*");
-}
-
-void init_const(void)
-{
-    if (!defined) {
-       NAME_START = (((float)NAME_START)/COLUMNS)*COLS;
-       FLAGS_START = (((float)FLAGS_START)/COLUMNS)*COLS;
-       PTYPE_START = (((float)PTYPE_START)/COLUMNS)*COLS;
-       FSTYPE_START = (((float)FSTYPE_START)/COLUMNS)*COLS;
-       SIZE_START = (((float)SIZE_START)/COLUMNS)*COLS;
-       COMMAND_LINE_X = (((float)COMMAND_LINE_X)/COLUMNS)*COLS;
-
-       COMMAND_LINE_Y = LINES - 4;
-       WARNING_START = LINES - 2;
-
-       if ((NUM_ON_SCREEN = COMMAND_LINE_Y - DISK_TABLE_START - 3) <= 0)
-           NUM_ON_SCREEN = 1;
-
-       COLUMNS = COLS;
-       defined = TRUE;
-    }
-}
-
-void draw_screen(void)
-{
-    int i;
-    char *line;
-
-    line = (char *)malloc((COLS+1)*sizeof(char));
-
-    if (warning_last_time) {
-       for (i = 0; i < COLS; i++) {
-           move(WARNING_START, i);
-           line[i] = inch();
-       }
-       line[COLS] = 0;
-    }
-
-    erase();
-
-    if (warning_last_time)
-       mvaddstr(WARNING_START, 0, line);
-
-
-    sprintf(line, "cfdisk %s", VERSION);
-    mvaddstr(HEADER_START, (COLS-strlen(line))/2, line);
-    sprintf(line, "Disk Drive: %s", disk_device);
-    mvaddstr(HEADER_START+2, (COLS-strlen(line))/2, line);
-    sprintf(line, "Heads: %d   Sectors per Track: %d   Cylinders: %d",
-           heads, sectors, cylinders);
-    mvaddstr(HEADER_START+3, (COLS-strlen(line))/2, line);
-
-    mvaddstr(DISK_TABLE_START, NAME_START, "Name");
-    mvaddstr(DISK_TABLE_START, FLAGS_START, "Flags");
-    mvaddstr(DISK_TABLE_START, PTYPE_START, "Part Type");
-    mvaddstr(DISK_TABLE_START, FSTYPE_START, "FS Type");
-    if (display_units == SECTORS)
-       mvaddstr(DISK_TABLE_START, SIZE_START, "  Sectors");
-    else if (display_units == CYLINDERS)
-       mvaddstr(DISK_TABLE_START, SIZE_START, "Cylinders");
-    else
-       mvaddstr(DISK_TABLE_START, SIZE_START, "Size (MB)");
-
-    move(DISK_TABLE_START+1, 1);
-    for (i = 1; i < COLS-1; i++)
-       addch('-');
-
-    if (NUM_ON_SCREEN >= num_parts)
-       for (i = 0; i < num_parts; i++)
-           draw_partition(i);
-    else
-       for (i = (cur_part/NUM_ON_SCREEN)*NUM_ON_SCREEN;
-            i < NUM_ON_SCREEN + (cur_part/NUM_ON_SCREEN)*NUM_ON_SCREEN &&
-            i < num_parts;
-            i++)
-           draw_partition(i);
-
-    free(line);
-}
-
-int draw_cursor(int move)
-{
-    if (move != 0 && (cur_part + move < 0 || cur_part + move >= num_parts))
-       return -1;
-
-    if (arrow_cursor)
-       mvaddstr(DISK_TABLE_START + cur_part + 2
-                - (cur_part/NUM_ON_SCREEN)*NUM_ON_SCREEN, 0, "   ");
-    else
-       draw_partition(cur_part);
-
-    cur_part += move;
-
-    if (((cur_part - move)/NUM_ON_SCREEN)*NUM_ON_SCREEN !=
-       (cur_part/NUM_ON_SCREEN)*NUM_ON_SCREEN)
-       draw_screen();
-
-    if (arrow_cursor)
-       mvaddstr(DISK_TABLE_START + cur_part + 2
-                - (cur_part/NUM_ON_SCREEN)*NUM_ON_SCREEN, 0, "-->");
-    else {
-       standout();
-       draw_partition(cur_part);
-       standend();
-    }
-
-    return 0;
-}
-
-void die(int dummy)
-{
-    signal(SIGINT, old_SIGINT);
-    signal(SIGTERM, old_SIGTERM);
-    mvcur(0, COLS-1, LINES-1, 0);
-    nl();
-    endwin();
-    fdexit(0);
-}
-
-void do_curses_fdisk(void)
-{
-    int done = FALSE;
-    char command;
-
-    initscr();
-    old_SIGINT = signal(SIGINT, die);
-    old_SIGTERM = signal(SIGTERM, die);
-#ifdef DEBUG
-    signal(SIGINT, old_SIGINT);
-    signal(SIGTERM, old_SIGTERM);
-#endif
-
-    cbreak();
-    noecho();
-    nonl();
-
-    init_const();
-
-    fill_p_info();
-
-    draw_screen();
-
-    while (!done) {
-       (void)draw_cursor(0);
-
-       if (p_info[cur_part].id == FREE_SPACE)
-           mvaddstr(COMMAND_LINE_Y, COMMAND_LINE_X, "Command [hnpquW?]: ");
-       else if (p_info[cur_part].id > 0)
-           mvaddstr(COMMAND_LINE_Y, COMMAND_LINE_X, "Command [bdhmpqtuW?]: ");
-       else
-           mvaddstr(COMMAND_LINE_Y, COMMAND_LINE_X, "Command [hpquW?]: ");
-
-       clrtoeol();
-       refresh();
-
-       clear_warning();
-
-       switch (command = getch()) {
-       case 'B':
-       case 'b':
-           if (p_info[cur_part].id > 0)
-               p_info[cur_part].flags ^= 0x80;
-           else
-               print_warning(NO_FLAGS);
-           break;
-       case 'D':
-       case 'd':
-           if (p_info[cur_part].id > 0) {
-               del_part(cur_part);
-               if (cur_part >= num_parts)
-                   cur_part = num_parts - 1;
-               draw_screen();
-           } else
-               print_warning(DEL_EMPTY);
-           break;
-       case 'G':
-       case 'g':
-           if (change_geometry())
-               draw_screen();
-           break;
-       case 'M':
-       case 'm':
-           if (p_info[cur_part].id > 0) {
-               if (p_info[cur_part].first_sector == 0 ||
-                   IS_LOGICAL(p_info[cur_part].num)) {
-                   if (p_info[cur_part].offset == sectors)
-                       p_info[cur_part].offset = 1;
-                   else
-                       p_info[cur_part].offset = sectors;
-                   draw_screen();
-               } else if (p_info[cur_part].offset != 0)
-                   p_info[cur_part].offset = 0;
-               else
-                   print_warning(MAX_UNMAXABLE);
-           } else
-               print_warning(MAX_UNMAXABLE);
-           break;
-       case 'N':
-       case 'n':
-           if (p_info[cur_part].id == FREE_SPACE) {
-               new_part(cur_part);
-               draw_screen();
-           } else if (p_info[cur_part].id == UNUSABLE)
-               print_warning(ADD_UNUSABLE);
-           else
-               print_warning(ADD_EXISTS);
-           break;
-       case 'P':
-       case 'p':
-           print_tables();
-           draw_screen();
-           break;
-       case 'Q':
-       case 'q':
-           done = TRUE;
-           break;
-       case 'T':
-       case 't':
-           if (p_info[cur_part].id > 0) {
-               change_id(cur_part);
-               draw_screen();
-           } else
-               print_warning(TYPE_EMPTY);
-           break;
-       case 'U':
-       case 'u':
-           if (display_units == MEGABYTES)
-               display_units = SECTORS;
-           else if (display_units == SECTORS)
-               display_units = CYLINDERS;
-           else if (display_units == CYLINDERS)
-               display_units = MEGABYTES;
-           draw_screen();
-           break;
-       case 'W':
-           write_part_table();
-           break;
-       case 'H':
-       case 'h':
-       case '?':
-           display_help();
-           draw_screen();
-           break;
-       case ESC:
-           if ((command = getch()) == '[') {
-               command = getch();
-               switch (command) {
-               case 'A' : /* Up arrow */
-                   if (!draw_cursor(-1))
-                       command = 0;
-                   else
-                       print_warning(NO_MORE_PARTS);
-                   break;
-               case 'B' : /* Down arrow */
-                   if (!draw_cursor(1))
-                       command = 0;
-                   else
-                       print_warning(NO_MORE_PARTS);
-                   break;
-               case 'C' : /* Right arrow */
-               case 'D' : /* Left arrow */
-               }
-           }
-           if (command)
-               putchar(BELL); /* CTRL-G */
-           break;
-       case REDRAWKEY:
-           clear();
-           draw_screen();
-           break;
-       default:
-           print_warning(BAD_COMMAND);
-           putchar(BELL); /* CTRL-G */
-       }
-    }
-
-    signal(SIGINT, old_SIGINT);
-    signal(SIGTERM, old_SIGTERM);
-    mvcur(0, COLS-1, LINES-1, 0);
-    nl();
-    endwin();
-    fdexit(0);
-}
-
-void copyright(void)
-{
-    fprintf(stderr, "Copyright (C) 1994 Kevin E. Martin\n");
-}
-
-void usage(char *prog_name)
-{
-    fprintf(stderr,
-           "%s: [-avz] [-c # cylinders] [-h # heads] [-s # sectors/track]\n",
-           prog_name);
-    fprintf(stderr,
-           "[ -P opt ] device\n");
-    copyright();
-}
-
-void main(int argc, char **argv)
-{
-    char c;
-    int i, len;
-
-    while ((c = getopt(argc, argv, "ac:h:s:vzP:")) != EOF)
-       switch (c) {
-       case 'a':
-           arrow_cursor = TRUE;
-           break;
-       case 'c':
-           cylinders = atoi(optarg);
-           if (cylinders <= 0 || cylinders > MAX_CYLINDERS) {
-               fprintf(stderr, "%s: %s\n", argv[0], BAD_CYLINDERS);
-               exit(1);
-           }
-           break;
-       case 'h':
-           heads = atoi(optarg);
-           if (heads <= 0 || heads > MAX_HEADS) {
-               fprintf(stderr, "%s: %s\n", argv[0], BAD_HEADS);
-               exit(1);
-           }
-           break;
-       case 's':
-           sectors = atoi(optarg);
-           if (sectors <= 0 || sectors > MAX_SECTORS) {
-               fprintf(stderr, "%s: %s\n", argv[0], BAD_SECTORS);
-               exit(1);
-           }
-           break;
-       case 'v':
-           fprintf(stderr, "cfdisk %s\n", VERSION);
-           copyright();
-           exit(0);
-       case 'z':
-           zero_table = TRUE;
-           break;
-       case 'P':
-           len = strlen(optarg);
-           for (i = 0; i < len; i++) {
-               switch (optarg[i]) {
-               case 'r':
-                   print_only |= PRINT_RAW_TABLE;
-                   break;
-               case 's':
-                   print_only |= PRINT_SECTOR_TABLE;
-                   break;
-               case 't':
-                   print_only |= PRINT_PARTITION_TABLE;
-                   break;
-               default:
-                   usage(argv[0]);
-                   break;
-               }
-           }
-           break;
-       default:
-           usage(argv[0]);
-           exit(1);
-       }
-
-    if (argc-optind == 1)
-       disk_device = argv[optind];
-    else if (argc-optind != 0) {
-       usage(argv[0]);
-       exit(1);
-    } else if ((fd = open(DEFAULT_DEVICE, O_RDWR)) < 0)
-       disk_device = ALTERNATE_DEVICE;
-    else close(fd);
-
-    if (print_only) {
-       fill_p_info();
-       if (print_only & PRINT_RAW_TABLE)
-           print_raw_table();
-       if (print_only & PRINT_SECTOR_TABLE)
-           print_p_info();
-       if (print_only & PRINT_PARTITION_TABLE)
-           print_part_table();
-    } else
-       do_curses_fdisk();
-}
diff --git a/disk-utils/cfdisk.c.orig b/disk-utils/cfdisk.c.orig
deleted file mode 100644 (file)
index 3b9f22f..0000000
+++ /dev/null
@@ -1,2066 +0,0 @@
-/****************************************************************************
- *
- *     CFDISK
- *
- * cfdisk is a curses based disk drive partitioning program that can
- * create partitions for a wide variety of operating systems including
- * Linux, MS-DOS and OS/2.
- *
- * cfdisk was inspired by the fdisk program, by A. V. Le Blanc
- * (LeBlanc@mcc.ac.uk).
- *
- *     Copyright (C) 1994 Kevin E. Martin (martin@cs.unc.edu)
- *
- * cfdisk is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * cfdisk is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with cfdisk; if not, write to the Free Software Foundation,
- * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Created:    Fri Jan 28 22:46:58 1994, martin@cs.unc.edu
- *
- ****************************************************************************/
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <unistd.h>
-#include <ctype.h>
-#include <errno.h>
-#include <getopt.h>
-#include <fcntl.h>
-#include <curses.h>
-#include <signal.h>
-#include <math.h>
-#include <sys/ioctl.h>
-#include <linux/genhd.h>
-#include <linux/hdreg.h>
-#include <linux/fs.h>          /* for BLKRRPART */
-
-typedef long ext2_loff_t;
-extern ext2_loff_t ext2_llseek(unsigned int fd,
-                              ext2_loff_t offset,
-                              unsigned int origin);
-
-#define VERSION "0.8 BETA (>2GB)"
-
-#define DEFAULT_DEVICE "/dev/hda"
-#define ALTERNATE_DEVICE "/dev/sda"
-
-#define LINE_LENGTH 80
-#define MAXIMUM_PARTS 60
-
-#define SECTOR_SIZE 512
-
-#define MAX_CYLINDERS 65535
-#define MAX_HEADS 255
-#define MAX_SECTORS 63
-
-#define ACTIVE_FLAG 0x80
-#define PART_TABLE_FLAG 0xAA55
-
-#define UNUSABLE -1
-#define FREE_SPACE 0x00
-#define EXTENDED 0x05
-#define LINUX_MINIX 0x81
-#define LINUX_SWAP 0x82
-#define LINUX 0x83
-
-#define ADD_EXISTS "This partition is already in use"
-#define ADD_UNUSABLE "This partition is unusable"
-#define DEL_EMPTY "Cannot delete an empty partition"
-#define ID_EMPTY "Cannot change FS Type to empty"
-#define ID_EXT "Cannot change FS Type to extended"
-#define NEED_EXT "No room to create the extended partition"
-#define NO_FLAGS "Cannot make this partition bootable"
-#define NO_MORE_PARTS "No more partitions"
-#define PRINT_OPEN_ERR "Cannot open file '%s'"
-#define TWO_EXTENDEDS "Cannot create logical drive here -- would create two extended partitions"
-#define TYPE_EMPTY "Cannot change the type of an empty partition"
-#define BAD_COMMAND "Illegal command"
-#define MAX_UNMAXABLE "Cannot maximize this partition"
-#define BAD_OPEN "Cannot open disk drive"
-#define BAD_SEEK "Cannot seek on disk drive"
-#define BAD_READ "Cannot read disk drive"
-#define BAD_WRITE "Cannot write disk drive"
-#define BAD_GEOMETRY "Cannot read disk drive geometry"
-#define BAD_PRIMARY "Bad primary partition"
-#define BAD_LOGICAL "Bad logical partition"
-#define BAD_CYLINDERS "Illegal cylinders value"
-#define BAD_HEADS "Illegal heads value"
-#define BAD_SECTORS "Illegal sectors value"
-#define WRITE_WARN "Warning!!  This may destroy data on your disk!"
-#define YES_NO "Please enter `yes' or `no'"
-#define WRITING_PART "Writing partition table to disk..."
-#define YES_WRITE "Wrote partition table to disk"
-#define NO_WRITE "Did not write partition table to disk"
-#define RRPART_FAILED "Wrote partition table, but re-read table failed.  Reboot to update table."
-
-#define PRI_OR_LOG -1
-#define PRIMARY -2
-#define LOGICAL -3
-
-#define COL_ID_WIDTH 20
-
-#define CR '\015'
-#define ESC '\033'
-#define DEL '\177'
-#define BELL '\007'
-/* '\014' == ^L */
-#define REDRAWKEY '\014'
-
-/* Display units */
-#define MEGABYTES 1
-#define SECTORS 2
-#define CYLINDERS 3
-
-#define GS_DEFAULT -1
-#define GS_ESCAPE -2
-
-#define PRINT_RAW_TABLE 1
-#define PRINT_SECTOR_TABLE 2
-#define PRINT_PARTITION_TABLE 4
-
-#define IS_PRIMARY(p) ((p) >= 0 && (p) < 4)
-#define IS_LOGICAL(p) ((p) > 3)
-
-#define round_int(d) ((double)((int)(d+0.5)))
-#define ceiling(d) ((double)(((d) != (int)(d)) ? (int)(d+1.0) : (int)(d)))
-
-#define set_hsc(h,s,c,sector) \
-{ \
-      s = sector % sectors + 1;        \
-      sector /= sectors;       \
-      h = sector % heads;      \
-      sector /= heads;         \
-      c = sector & 0xFF;       \
-      s |= (sector >> 2) & 0xC0;\
-}
-
-#define ALIGNMENT 2
-typedef union {
-    struct {
-       unsigned char align[ALIGNMENT];
-       unsigned char b[SECTOR_SIZE];
-    } c;
-    struct {
-       unsigned char align[ALIGNMENT];
-       unsigned char buffer[0x1BE];
-       struct partition part[4];
-       unsigned short flag;
-    } p;
-} partition_table;
-
-typedef struct {
-    int first_sector;  /* first sector in partition */
-    int last_sector;   /* last sector in partition */
-    int offset;                /* offset from first sector to start of data */
-    int flags;         /* active == 0x80 */
-    int id;            /* filesystem type */
-    int num;           /* number of partition -- primary vs. logical */
-} partition_info;
-
-char *disk_device = DEFAULT_DEVICE;
-int fd;
-int heads = 0;
-int sectors = 0;
-int cylinders = 0;
-int changed = FALSE;
-int opened = FALSE;
-
-partition_info p_info[MAXIMUM_PARTS];
-partition_info ext_info;
-int num_parts = 0;
-
-int logical = 0;
-int logical_sectors[MAXIMUM_PARTS];
-
-__sighandler_t old_SIGINT, old_SIGTERM;
-
-int arrow_cursor = FALSE;
-int display_units = MEGABYTES;
-int zero_table = FALSE;
-int print_only = 0;
-
-/* Curses screen information */
-int cur_part = 0;
-int warning_last_time = FALSE;
-int defined = FALSE;
-int COLUMNS = 80;
-int NUM_ON_SCREEN = 1;
-
-/* Y coordinates */
-int HEADER_START = 0;
-int DISK_TABLE_START = 5;
-int WARNING_START = 23;
-int COMMAND_LINE_Y = 21;
-
-/* X coordinates */
-int NAME_START = 4;
-int FLAGS_START = 16;
-int PTYPE_START = 30;
-int FSTYPE_START = 45;
-int SIZE_START = 70;
-int COMMAND_LINE_X = 5;
-
-#define NUM_PART_TYPES 256
-char *partition_type[NUM_PART_TYPES] = {
-    [LINUX_MINIX] = "Linux/MINIX",
-    [LINUX_SWAP]  = "Linux Swap",
-    [LINUX]       = "Linux",
-    [FREE_SPACE]  = "Free Space",
-    [EXTENDED]    = "Extended",
-    [0x01]        = "DOS 12-bit FAT",
-    [0x04]        = "DOS 16-bit < 32Mb",
-    [0x06]        = "DOS 16-bit >=32Mb",
-    [0x07]        = "OS/2 HPFS",
-    [0x0A]        = "OS/2 Boot Manager",
-    [0xA5]        = "BSD/386",
-
-/* The rest of these are taken from A. V. Le Blanc's (LeBlanc@mcc.ac.uk)
- * fdisk program.  I do not know where they came from, but I include
- * them for completeness.
- */
-
-    [0x02]        = "XENIX root",
-    [0x03]        = "XENIX usr",
-    [0x08]        = "AIX",
-    [0x09]        = "AIX bootable",
-    [0x40]        = "Venix 80286",
-    [0x51]        = "Novell?",
-    [0x52]        = "Microport",
-    [0x63]        = "GNU HURD",
-    [0x64]        = "Novell",
-    [0x75]        = "PC/IX",
-    [0x80]        = "Old MINIX",
-    [0x93]        = "Amoeba",
-    [0x94]        = "Amoeba BBT",
-    [0xB7]        = "BSDI fs",
-    [0xB8]        = "BSDI swap",
-    [0xC7]        = "Syrinx",
-    [0xDB]        = "CP/M",
-    [0xE1]        = "DOS access",
-    [0xE3]        = "DOS R/O",
-    [0xF2]        = "DOS secondary",
-    [0xFF]        = "BBT"
-};
-
-void fdexit(int ret)
-{
-    if (opened)
-       close(fd);
-
-    if (changed) {
-       fprintf(stderr, "Disk has been changed.\n");
-       fprintf(stderr, "Reboot the system to ensure the partition "
-                       "table is correctly updated.\n");
-       
-       fprintf( stderr, "\nWARNING: If you have created or modified any\n"
-                        "DOS 6.x partitions, please see the cfdisk manual\n"
-                        "page for additional information.\n" );
-    }
-
-
-    exit(ret);
-}
-
-int get_string(char *str, int len, char *def)
-{
-    char c;
-    int i = 0;
-    int x, y;
-    int use_def = FALSE;
-
-    getyx(stdscr, y, x);
-    clrtoeol();
-
-    str[i] = 0;
-
-    if (def != NULL) {
-       mvaddstr(y, x, def);
-       move(y, x);
-       use_def = TRUE;
-    }
-
-    refresh();
-    while ((c = getch()) != '\n' && c != CR) {
-       switch (c) {
-       case ESC:
-           move(y, x);
-           clrtoeol();
-           refresh();
-           return GS_ESCAPE;
-       case DEL:
-       case '\b':
-           if (i > 0) {
-               str[--i] = 0;
-               mvaddch(y, x+i, ' ');
-               move(y, x+i);
-           } else if (use_def) {
-               clrtoeol();
-               use_def = FALSE;
-           } else
-               putchar(BELL);
-           break;
-       default:
-           if (i < len && isprint(c)) {
-               mvaddch(y, x+i, c);
-               if (use_def) {
-                   clrtoeol();
-                   use_def = FALSE;
-               }
-               str[i++] = c;
-               str[i] = 0;
-           } else
-               putchar(BELL);
-       }
-       refresh();
-    }
-
-    if (use_def)
-       return GS_DEFAULT;
-    else
-       return i;
-}
-
-void clear_warning(void)
-{
-    int i;
-
-    if (!warning_last_time)
-       return;
-
-    move(WARNING_START,0);
-    for (i = 0; i < COLS; i++)
-       addch(' ');
-
-    warning_last_time = FALSE;
-}
-
-void print_warning(char *s)
-{
-    mvaddstr(WARNING_START, (COLS-strlen(s))/2, s);
-    putchar(BELL); /* CTRL-G */
-
-    warning_last_time = TRUE;
-}
-
-void fatal(char *s)
-{
-    char str[LINE_LENGTH];
-
-    sprintf(str, "FATAL ERROR: %s", s);
-    mvaddstr(WARNING_START, (COLS-strlen(str))/2, str);
-    sprintf(str, "Press any key to exit fdisk");
-    mvaddstr(WARNING_START+1, (COLS-strlen(str))/2, str);
-    putchar(BELL); /* CTRL-G */
-
-    refresh();
-
-    (void)getch();
-
-    signal(SIGINT, old_SIGINT);
-    signal(SIGTERM, old_SIGTERM);
-    mvcur(0, COLS-1, LINES-1, 0);
-    nl();
-    endwin();
-    fdexit(1);
-}
-
-void read_sector(char *buffer, int sect_num)
-{
-    if (ext2_llseek(fd, sect_num*SECTOR_SIZE, SEEK_SET) < 0)
-       fatal(BAD_SEEK);
-    if (read(fd, buffer, SECTOR_SIZE) != SECTOR_SIZE)
-       fatal(BAD_READ);
-}
-
-void write_sector(char *buffer, int sect_num)
-{
-    if (ext2_llseek(fd, sect_num*SECTOR_SIZE, SEEK_SET) < 0)
-       fatal(BAD_SEEK);
-    if (write(fd, buffer, SECTOR_SIZE) != SECTOR_SIZE)
-       fatal(BAD_WRITE);
-}
-
-void check_part_info(void)
-{
-    int i, pri = 0, log = 0;
-
-    for (i = 0; i < num_parts; i++)
-       if (p_info[i].id > 0 && IS_PRIMARY(p_info[i].num))
-           pri++;
-       else if (p_info[i].id > 0 && IS_LOGICAL(p_info[i].num))
-           log++;
-    if (ext_info.id == EXTENDED)
-       if (log > 0)
-           pri++;
-       else {
-           ext_info.first_sector = 0;
-           ext_info.last_sector = 0;
-           ext_info.offset = 0;
-           ext_info.flags = 0;
-           ext_info.id = FREE_SPACE;
-           ext_info.num = PRIMARY;
-       }
-
-    if (pri >= 4)
-       for (i = 0; i < num_parts; i++)
-           if (p_info[i].id == FREE_SPACE || p_info[i].id == UNUSABLE)
-               if (ext_info.id == EXTENDED)
-                   if (p_info[i].first_sector >= ext_info.first_sector &&
-                       p_info[i].last_sector <= ext_info.last_sector) {
-                       p_info[i].id = FREE_SPACE;
-                       p_info[i].num = LOGICAL;
-                   } else if (i > 0 &&
-                              p_info[i-1].first_sector >=
-                              ext_info.first_sector &&
-                              p_info[i-1].last_sector <=
-                              ext_info.last_sector) {
-                       p_info[i].id = FREE_SPACE;
-                       p_info[i].num = LOGICAL;
-                   } else if (i < num_parts-1 &&
-                              p_info[i+1].first_sector >=
-                              ext_info.first_sector &&
-                              p_info[i+1].last_sector <=
-                              ext_info.last_sector) {
-                       p_info[i].id = FREE_SPACE;
-                       p_info[i].num = LOGICAL;
-                   } else
-                       p_info[i].id = UNUSABLE;
-               else /* if (ext_info.id != EXTENDED) */
-                   p_info[i].id = UNUSABLE;
-           else /* if (p_info[i].id > 0) */
-               while (0); /* Leave these alone */
-    else /* if (pri < 4) */
-       for (i = 0; i < num_parts; i++) {
-           if (p_info[i].id == UNUSABLE)
-               p_info[i].id = FREE_SPACE;
-           if (p_info[i].id == FREE_SPACE)
-               if (ext_info.id == EXTENDED)
-                   if (p_info[i].first_sector >= ext_info.first_sector &&
-                       p_info[i].last_sector <= ext_info.last_sector)
-                       p_info[i].num = LOGICAL;
-                   else if (i > 0 &&
-                            p_info[i-1].first_sector >=
-                            ext_info.first_sector &&
-                            p_info[i-1].last_sector <=
-                            ext_info.last_sector)
-                       p_info[i].num = PRI_OR_LOG;
-                   else if (i < num_parts-1 &&
-                            p_info[i+1].first_sector >=
-                            ext_info.first_sector &&
-                            p_info[i+1].last_sector <=
-                            ext_info.last_sector)
-                       p_info[i].num = PRI_OR_LOG;
-                   else
-                       p_info[i].num = PRIMARY;
-               else /* if (ext_info.id != EXTENDED) */
-                   p_info[i].num = PRI_OR_LOG;
-           else /* if (p_info[i].id > 0) */
-               while (0); /* Leave these alone */
-       }
-}
-
-void remove_part(int i)
-{
-    int p;
-
-    for (p = i; p < num_parts; p++)
-       p_info[p] = p_info[p+1];
-
-    num_parts--;
-}
-
-void insert_part(int i, int num, int id, int flags, int first, int last,
-                int offset)
-{
-    int p;
-
-    for (p = num_parts; p > i; p--)
-        p_info[p] = p_info[p-1];
-
-    p_info[i].first_sector = first;
-    p_info[i].last_sector = last;
-    p_info[i].offset = offset;
-    p_info[i].flags = flags;
-    p_info[i].id = id;
-    p_info[i].num = num;
-
-    num_parts++;
-}
-
-void del_part(int i)
-{
-    int num = p_info[i].num;
-
-    if (i > 0 && (p_info[i-1].id == FREE_SPACE ||
-                 p_info[i-1].id == UNUSABLE)) {
-       /* Merge with previous partition */
-       p_info[i-1].last_sector = p_info[i].last_sector;
-       remove_part(i--);
-    }
-
-    if (i < num_parts - 1 && (p_info[i+1].id == FREE_SPACE ||
-                             p_info[i+1].id == UNUSABLE)) {
-       /* Merge with next partition */
-       p_info[i+1].first_sector = p_info[i].first_sector;
-       remove_part(i);
-    }
-
-    if (i > 0)
-       p_info[i].first_sector = p_info[i-1].last_sector + 1;
-    else
-       p_info[i].first_sector = 0;
-
-    if (i < num_parts - 1)
-       p_info[i].last_sector = p_info[i+1].first_sector - 1;
-    else
-       p_info[i].last_sector = sectors*heads*cylinders - 1;
-
-    p_info[i].offset = 0;
-    p_info[i].flags = 0;
-    p_info[i].id = FREE_SPACE;
-    p_info[i].num = PRI_OR_LOG;
-
-    if (IS_LOGICAL(num)) {
-       /* We have a logical partition --> shrink the extended partition
-        * if (1) this is the first logical drive, or (2) this is the
-        * last logical drive; and if there are any other logical drives
-        * then renumber the ones after "num".
-        */
-       if (i == 0 || (i > 0 && IS_PRIMARY(p_info[i-1].num)))
-           ext_info.first_sector = p_info[i].last_sector + 1;
-       if (i == num_parts-1 ||
-           (i < num_parts-1 && IS_PRIMARY(p_info[i+1].num)))
-           ext_info.last_sector = p_info[i].first_sector - 1;
-       for (i = 0; i < num_parts; i++)
-           if (p_info[i].num > num)
-               p_info[i].num--;
-    }
-
-    /* Clean up the rest of the partitions */
-    check_part_info();
-}
-
-int add_part(int num, int id, int flags, int first, int last, int offset)
-{
-    int i, pri = 0, log = 0;
-
-    if (num_parts == MAXIMUM_PARTS ||
-       first < 0 ||
-       first >= cylinders*heads*sectors ||
-       last < 0 ||
-       last >= cylinders*heads*sectors)
-       return -1;
-
-    for (i = 0; i < num_parts; i++)
-       if (p_info[i].id > 0 && IS_PRIMARY(p_info[i].num))
-           pri++;
-       else if (p_info[i].id > 0 && IS_LOGICAL(p_info[i].num))
-           log++;
-    if (ext_info.id == EXTENDED && log > 0)
-       pri++;
-
-    if (IS_PRIMARY(num))
-       if (pri >= 4)
-           return -1;
-       else
-           pri++;
-
-    for (i = 0; p_info[i].last_sector < first; i++);
-
-    if (p_info[i].id != FREE_SPACE || last > p_info[i].last_sector)
-       return -1;
-
-    if (id == EXTENDED)
-       if (ext_info.id != FREE_SPACE)
-           return -1;
-       else if (IS_PRIMARY(num)) {
-           ext_info.first_sector = first;
-           ext_info.last_sector = last;
-           ext_info.offset = offset;
-           ext_info.flags = flags;
-           ext_info.id = EXTENDED;
-           ext_info.num = num;
-
-           return 0;
-       } else
-           return -1;
-
-    if (IS_LOGICAL(num)) {
-       if (ext_info.id != EXTENDED) {
-           print_warning("!!!! Internal error creating logical "
-                         "drive with no extended partition !!!!");
-       } else {
-           /* We might have a logical partition outside of the extended
-            * partition's range --> we have to extend the extended
-            * partition's range to encompass this new partition, but we
-            * must make sure that there are no primary partitions between
-            * it and the closest logical drive in extended partition.
-            */
-           if (first < ext_info.first_sector) {
-               if (i < num_parts-1 && IS_PRIMARY(p_info[i+1].num)) {
-                   print_warning(TWO_EXTENDEDS);
-                   return -1;
-               } else {
-                   if (first == 0) {
-                       ext_info.first_sector = 0;
-                       ext_info.offset = first = offset;
-                   } else
-                       ext_info.first_sector = first;
-               }
-           } else if (last > ext_info.last_sector) {
-               if (i > 0 && IS_PRIMARY(p_info[i-1].num)) {
-                   print_warning(TWO_EXTENDEDS);
-                   return -1;
-               } else
-                   ext_info.last_sector = last;
-           }
-       }
-    }
-
-    if (first != p_info[i].first_sector &&
-       !(IS_LOGICAL(num) && first == offset)) {
-       insert_part(i, PRI_OR_LOG, FREE_SPACE, 0,
-                   p_info[i].first_sector, first-1, 0);
-       i++;
-    }
-
-    if (last != p_info[i].last_sector)
-       insert_part(i+1, PRI_OR_LOG, FREE_SPACE, 0,
-                   last+1, p_info[i].last_sector, 0);
-
-    p_info[i].first_sector = first;
-    p_info[i].last_sector = last;
-    p_info[i].offset = offset;
-    p_info[i].flags = flags;
-    p_info[i].id = id;
-    p_info[i].num = num;
-
-    check_part_info();
-
-    return 0;
-}
-
-int find_primary(void)
-{
-    int num = 0, cur = 0;
-
-    while (cur < num_parts && IS_PRIMARY(num))
-       if ((p_info[cur].id > 0 && p_info[cur].num == num) ||
-           (ext_info.id == EXTENDED && ext_info.num == num)) {
-           num++;
-           cur = 0;
-       } else
-           cur++;
-
-    if (!IS_PRIMARY(num))
-       return -1;
-    else
-       return num;
-}
-
-int find_logical(int i)
-{
-    int num = -1;
-    int j;
-
-    for (j = i; j < num_parts && num == -1; j++)
-       if (p_info[j].id > 0 && IS_LOGICAL(p_info[j].num))
-           num = p_info[j].num;
-
-    if (num == -1) {
-       num = 4;
-       for (j = 0; j < num_parts; j++)
-           if (p_info[j].id > 0 && p_info[j].num == num)
-               num++;
-    }
-
-    return num;
-}
-
-void inc_logical(int i)
-{
-    int j;
-
-    for (j = i; j < num_parts; j++)
-       if (p_info[j].id > 0 && IS_LOGICAL(p_info[j].num))
-           p_info[j].num++;
-}
-
-void new_part(int i)
-{
-    char response[LINE_LENGTH], def[LINE_LENGTH];
-    char c;
-    int first = p_info[i].first_sector;
-    int last = p_info[i].last_sector;
-    int offset = 0;
-    int flags = 0;
-    int id = LINUX;
-    int num = -1;
-    int num_sects = last - first + 1;
-    int len, ext, j;
-
-    if (p_info[i].num == PRI_OR_LOG) {
-       mvaddstr(COMMAND_LINE_Y, COMMAND_LINE_X, "Primary or logical [pl]: ");
-       clrtoeol();
-       refresh();
-       while (toupper(c = getch()) != 'P' && toupper(c) != 'L' && c != ESC);
-       if (toupper(c) == 'P')
-           num = find_primary();
-       else if (toupper(c) == 'L')
-           num = find_logical(i);
-       else
-           return;
-    } else if (p_info[i].num == PRIMARY)
-       num = find_primary();
-    else if (p_info[i].num == LOGICAL)
-       num = find_logical(i);
-    else
-       print_warning("!!! Internal error !!!");
-
-    sprintf(def, "%.2f", ceiling(num_sects/20.48)/100);
-    mvaddstr(COMMAND_LINE_Y, COMMAND_LINE_X, "Size (in MB): ");
-    if ((len = get_string(response, LINE_LENGTH, def)) <= 0 &&
-       len != GS_DEFAULT)
-       return;
-    else if (len > 0) {
-#define num_cyls(bytes) (round_int(bytes/SECTOR_SIZE/(sectors*heads)))
-       for (j = 0;
-            j < len-1 && (isdigit(response[j]) || response[j] == '.');
-            j++);
-       if (toupper(response[j]) == 'K') {
-           num_sects = num_cyls(atof(response)*1024)*sectors*heads;
-       } else if (toupper(response[j]) == 'M') {
-           num_sects = num_cyls(atof(response)*1024*1024)*sectors*heads;
-       } else if (toupper(response[j]) == 'C') {
-           num_sects = round_int(atof(response))*sectors*heads;
-       } else if (toupper(response[j]) == 'S') {
-           num_sects = round_int(atof(response));
-       } else {
-           num_sects = num_cyls(atof(response)*1024*1024)*sectors*heads;
-       }
-    }
-
-    if (num_sects <= 0 ||
-       num_sects > p_info[i].last_sector - p_info[i].first_sector + 1)
-       return;
-
-    if (num_sects < p_info[i].last_sector - p_info[i].first_sector + 1) {
-       /* Determine where inside free space to put partition.
-        */
-       mvaddstr(COMMAND_LINE_Y, COMMAND_LINE_X,
-                "Add partition at beginning or end of free space [be]: ");
-       clrtoeol();
-       refresh();
-       while (toupper(c = getch()) != 'B' && toupper(c) != 'E' && c != ESC);
-       if (toupper(c) == 'B')
-           last = first + num_sects - 1;
-       else if (toupper(c) == 'E')
-           first = last - num_sects + 1;
-       else
-           return;
-    }
-
-    if (IS_LOGICAL(num) && ext_info.id != EXTENDED) {
-       /* We want to add a logical partition, but need to create an
-        * extended partition first.
-        */
-       if ((ext = find_primary()) < 0) {
-           print_warning(NEED_EXT);
-           return;
-       }
-       (void)add_part(ext, EXTENDED, 0, first, last,
-                      (first == 0 ? sectors : 0));
-    }
-
-    if (IS_LOGICAL(num))
-       inc_logical(i);
-
-    /* Now we have a complete partition to ourselves */
-    if (first == 0 || IS_LOGICAL(num))
-       offset = sectors;
-
-    (void)add_part(num, id, flags, first, last, offset);
-}
-
-void clear_p_info(void)
-{
-    num_parts = 1;
-    p_info[0].first_sector = 0;
-    p_info[0].last_sector = sectors*heads*cylinders - 1;
-    p_info[0].offset = 0;
-    p_info[0].flags = 0;
-    p_info[0].id = FREE_SPACE;
-    p_info[0].num = PRI_OR_LOG;
-
-    ext_info.first_sector = 0;
-    ext_info.last_sector = 0;
-    ext_info.offset = 0;
-    ext_info.flags = 0;
-    ext_info.id = FREE_SPACE;
-    ext_info.num = PRIMARY;
-}
-
-void fill_p_info(void)
-{
-    int p, i;
-    struct hd_geometry geometry;
-    partition_table buffer;
-    partition_info tmp_ext = { 0, 0, 0, 0, FREE_SPACE, PRIMARY };
-
-    if ((fd = open(disk_device, O_RDWR)) < 0)
-       fatal(BAD_OPEN);
-    read_sector(buffer.c.b, 0);
-
-    if (!ioctl(fd, HDIO_GETGEO, &geometry)) {
-       if (!heads)
-           heads = geometry.heads;
-       if (!sectors)
-           sectors = geometry.sectors;
-       if (!cylinders)
-           cylinders = geometry.cylinders;
-    }
-
-    if (!heads || !sectors || !cylinders)
-       fatal(BAD_GEOMETRY);
-
-    clear_p_info();
-
-    if (!zero_table) {
-       for (i = 0; i < 4; i++) {
-           if (buffer.p.part[i].sys_ind > 0 &&
-               add_part(i,
-                        buffer.p.part[i].sys_ind,
-                        buffer.p.part[i].boot_ind,
-                        ((buffer.p.part[i].start_sect <= sectors) ?
-                         0 : buffer.p.part[i].start_sect),
-                        buffer.p.part[i].start_sect +
-                        buffer.p.part[i].nr_sects - 1,
-                        ((buffer.p.part[i].start_sect <= sectors) ?
-                         buffer.p.part[i].start_sect : 0))) {
-               fatal(BAD_PRIMARY);
-           }
-           if (buffer.p.part[i].sys_ind == EXTENDED)
-               tmp_ext = ext_info;
-       }
-
-       if (tmp_ext.id == EXTENDED) {
-           ext_info = tmp_ext;
-           logical_sectors[logical] = ext_info.first_sector;
-           read_sector(buffer.c.b, logical_sectors[logical++]);
-           i = 4;
-           do {
-               for (p = 0;
-                    p < 4 && (!buffer.p.part[p].sys_ind ||
-                              buffer.p.part[p].sys_ind == 5);
-                    p++);
-               if (p > 3)
-                   fatal(BAD_LOGICAL);
-
-               if (add_part(i++,
-                            buffer.p.part[p].sys_ind,
-                            buffer.p.part[p].boot_ind,
-                            logical_sectors[logical-1],
-                            logical_sectors[logical-1] +
-                            buffer.p.part[p].start_sect +
-                            buffer.p.part[p].nr_sects - 1,
-                            buffer.p.part[p].start_sect)) {
-                   fatal(BAD_LOGICAL);
-               }
-
-               for (p = 0;
-                    p < 4 && buffer.p.part[p].sys_ind != 5;
-                    p++);
-               if (p < 4) {
-                   logical_sectors[logical] =
-                       ext_info.first_sector + buffer.p.part[p].start_sect;
-                   read_sector(buffer.c.b, logical_sectors[logical++]);
-               }
-           } while (p < 4 && logical < MAXIMUM_PARTS-4);
-       }
-    }
-}
-
-void fill_part_table(struct partition *p, partition_info *pi)
-{
-    int sects;
-
-    p->boot_ind = pi->flags;
-    p->sys_ind = pi->id;
-    if (IS_LOGICAL(pi->num))
-       p->start_sect = pi->offset;
-    else
-       p->start_sect = pi->first_sector + pi->offset;
-    p->nr_sects = pi->last_sector - (pi->first_sector+pi->offset) + 1;
-    sects = (((pi->first_sector+pi->offset)/(sectors*heads) > 1023) ?
-            heads*sectors*1024 - 1 : pi->first_sector+pi->offset);
-    set_hsc(p->head, p->sector, p->cyl, sects);
-    sects = ((pi->last_sector/(sectors*heads) > 1023) ?
-            heads*sectors*1024 - 1 : pi->last_sector);
-    set_hsc(p->end_head, p->end_sector, p->end_cyl, sects);
-}
-
-void fill_primary_table(partition_table *buffer)
-{
-    int i;
-
-    /* Zero out existing table */
-    for (i = 0x1BE; i < SECTOR_SIZE; i++)
-       buffer->c.b[i] = 0;
-
-    for (i = 0; i < num_parts; i++)
-       if (IS_PRIMARY(p_info[i].num))
-           fill_part_table(&(buffer->p.part[p_info[i].num]), &(p_info[i]));
-
-    if (ext_info.id == EXTENDED)
-       fill_part_table(&(buffer->p.part[ext_info.num]), &ext_info);
-
-    buffer->p.flag = PART_TABLE_FLAG;
-}
-
-void fill_logical_table(partition_table *buffer, partition_info *pi)
-{
-    struct partition *p;
-    int i, sects;
-
-    for (i = 0; i < logical && pi->first_sector != logical_sectors[i]; i++);
-    if (i == logical || buffer->p.flag != (unsigned short)PART_TABLE_FLAG)
-       for (i = 0; i < SECTOR_SIZE; i++)
-           buffer->c.b[i] = 0;
-
-    /* Zero out existing table */
-    for (i = 0x1BE; i < SECTOR_SIZE; i++)
-       buffer->c.b[i] = 0;
-
-    fill_part_table(&(buffer->p.part[0]), pi);
-
-    for (i = 0;
-        i < num_parts && pi->num != p_info[i].num - 1;
-        i++);
-
-    if (i < num_parts) {
-       p = &(buffer->p.part[1]);
-       pi = &(p_info[i]);
-
-       p->boot_ind = 0;
-       p->sys_ind = 5;
-       p->start_sect = pi->first_sector - ext_info.first_sector;
-       p->nr_sects = pi->last_sector - pi->first_sector + 1;
-       sects = ((pi->first_sector/(sectors*heads) > 1023) ?
-                heads*sectors*1024 - 1 : pi->first_sector);
-       set_hsc(p->head, p->sector, p->cyl, sects);
-       sects = ((pi->last_sector/(sectors*heads) > 1023) ?
-                heads*sectors*1024 - 1 : pi->last_sector);
-       set_hsc(p->end_head, p->end_sector, p->end_cyl, sects);
-    }
-
-    buffer->p.flag = PART_TABLE_FLAG;
-}
-
-void write_part_table(void)
-{
-    int i, done = FALSE, len;
-    partition_table buffer;
-    char response[LINE_LENGTH];
-
-    print_warning(WRITE_WARN);
-
-    while (!done) {
-       mvaddstr(COMMAND_LINE_Y, COMMAND_LINE_X,
-                "Are you sure you want write the partition table to disk? (yes or no): ");
-       
-       len = get_string(response, LINE_LENGTH, NULL);
-
-       clear_warning();
-
-       if (len == GS_ESCAPE)
-           return;
-       else if (len == 2 &&
-                toupper(response[0]) == 'N' &&
-                toupper(response[1]) == 'O') {
-           print_warning(NO_WRITE);
-           return;
-       } else if (len == 3 &&
-                  toupper(response[0]) == 'Y' &&
-                  toupper(response[1]) == 'E' &&
-                  toupper(response[2]) == 'S')
-           done = TRUE;
-       else
-           print_warning(YES_NO);
-    }
-
-    clear_warning();
-    print_warning(WRITING_PART);
-    refresh();
-    
-    read_sector(buffer.c.b, 0);
-    fill_primary_table(&buffer);
-    write_sector(buffer.c.b, 0);
-
-    for (i = 0; i < num_parts; i++)
-       if (IS_LOGICAL(p_info[i].num)) {
-           /* Read the extended partition table from disk ??? KEM */
-           read_sector(buffer.c.b, p_info[i].first_sector);
-           fill_logical_table(&buffer, &(p_info[i]));
-           write_sector(buffer.c.b, p_info[i].first_sector);
-       }
-
-    sync();
-    sleep(2);
-    if (!ioctl(fd,BLKRRPART))
-       changed = TRUE;
-    sync();
-    sleep(4);
-
-    clear_warning();
-    if (changed)
-       print_warning(YES_WRITE);
-    else
-       print_warning(RRPART_FAILED);
-}
-
-void fp_printf(FILE *fp, char *format, ...)
-{
-    va_list args;
-    char buf[1024];
-    int y, x;
-
-    va_start(args, format);
-    vsprintf(buf, format, args);
-    va_end(args);
-
-    if (fp == NULL) {
-       /* The following works best if the string to be printed has at
-           most only one newline. */
-       printw("%s", buf);
-       getyx(stdscr, y, x);
-       if (y >= COMMAND_LINE_Y-2) {
-           mvaddstr(COMMAND_LINE_Y, COMMAND_LINE_X,
-                    "Press any key to continue...");
-           clrtoeol();
-           refresh();
-           (void)getch();
-           erase();
-           move(0, 0);
-       }
-    } else
-       fprintf(fp, "%s", buf);
-}
-
-#define MAX_PER_LINE 16
-void print_file_buffer(FILE *fp, char *buffer)
-{
-    int i,l;
-
-    for (i = 0, l = 0; i < SECTOR_SIZE; i++, l++) {
-       if (l == 0)
-           fp_printf(fp, "0x%03X:", i);
-       fp_printf(fp, " %02X", (unsigned char) buffer[i]);
-       if (l == MAX_PER_LINE - 1) {
-           fp_printf(fp, "\n");
-           l = -1;
-       }
-    }
-    if (l > 0)
-       fp_printf(fp, "\n");
-    fp_printf(fp, "\n");
-}
-
-void print_raw_table(void)
-{
-    int i, to_file;
-    partition_table buffer;
-    char fname[LINE_LENGTH];
-    FILE *fp;
-
-    if (print_only) {
-       fp = stdout;
-       to_file = TRUE;
-    } else {
-       mvaddstr(COMMAND_LINE_Y, COMMAND_LINE_X,
-                "Enter filename or press RETURN to display on screen: ");
-
-       if ((to_file = get_string(fname, LINE_LENGTH, NULL)) < 0)
-           return;
-
-       if (to_file) {
-           if ((fp = fopen(fname, "w")) == NULL) {
-               char errstr[LINE_LENGTH];
-               sprintf(errstr, PRINT_OPEN_ERR, fname);
-               print_warning(errstr);
-               return;
-           }
-       } else {
-           fp = NULL;
-           erase();
-           move(0, 0);
-       }
-    }
-
-    fp_printf(fp, "Disk Drive: %s\n", disk_device);
-
-    read_sector(buffer.c.b, 0);
-    fill_primary_table(&buffer);
-    print_file_buffer(fp, buffer.c.b);
-
-    for (i = 0; i < num_parts; i++)
-       if (IS_LOGICAL(p_info[i].num)) {
-           read_sector(buffer.c.b, p_info[i].first_sector);
-           fill_logical_table(&buffer, &(p_info[i]));
-           print_file_buffer(fp, buffer.c.b);
-       }
-
-    if (to_file) {
-       if (!print_only)
-           fclose(fp);
-    } else {
-       mvaddstr(COMMAND_LINE_Y, COMMAND_LINE_X,
-                "Press any key to continue...");
-       clrtoeol();
-       refresh();
-       (void)getch();
-    }
-}
-
-void print_p_info_entry(FILE *fp, partition_info *p)
-{
-    int size;
-    char part_str[21];
-
-    if (p->id == UNUSABLE)
-       fp_printf(fp, "   None   ");
-    else if (p->id == FREE_SPACE && p->num == PRI_OR_LOG)
-       fp_printf(fp, "   Pri/Log");
-    else if (p->id == FREE_SPACE && p->num == PRIMARY)
-       fp_printf(fp, "   Primary");
-    else if (p->id == FREE_SPACE && p->num == LOGICAL)
-       fp_printf(fp, "   Logical");
-    else
-       fp_printf(fp, "%2d %-7.7s", p->num+1,
-                 IS_LOGICAL(p->num) ? "Logical" : "Primary");
-
-    fp_printf(fp, " ");
-
-    fp_printf(fp, "%7d%c", p->first_sector,
-             ((p->first_sector/(sectors*heads)) !=
-              ((float)p->first_sector/(sectors*heads)) ?
-              '*' : ' '));
-
-    fp_printf(fp, " ");
-
-    fp_printf(fp, "%7d%c", p->last_sector,
-             (((p->last_sector+1)/(sectors*heads)) !=
-              ((float)(p->last_sector+1)/(sectors*heads)) ?
-              '*' : ' '));
-
-    fp_printf(fp, " ");
-
-    fp_printf(fp, "%6d%c", p->offset,
-             ((((p->first_sector == 0 || IS_LOGICAL(p->num)) &&
-                (p->offset != sectors)) ||
-               (p->first_sector != 0 && IS_PRIMARY(p->num) &&
-                p->offset != 0)) ?
-              '#' : ' '));
-
-    fp_printf(fp, " ");
-
-    size = p->last_sector - p->first_sector + 1;
-    fp_printf(fp, "%7d%c", size,
-             ((size/(sectors*heads)) != ((float)size/(sectors*heads)) ?
-              '*' : ' '));
-
-    fp_printf(fp, " ");
-
-    if (p->id == UNUSABLE)
-       sprintf(part_str, "%.16s", "Unusable");
-    else if (p->id == FREE_SPACE)
-       sprintf(part_str, "%.16s", "Free Space");
-    else if (partition_type[p->id])
-       sprintf(part_str, "%.16s (%02X)", partition_type[p->id], p->id);
-    else
-       sprintf(part_str, "%.16s (%02X)", "Unknown", p->id);
-    fp_printf(fp, "%-21.21s", part_str);
-
-    fp_printf(fp, " ");
-
-    if (p->flags == ACTIVE_FLAG)
-       fp_printf(fp, "Boot (%02X)", p->flags);
-    else if (p->flags != 0)
-       fp_printf(fp, "Unknown (%02X)", p->flags);
-    else
-       fp_printf(fp, "None (%02X)", p->flags);
-
-    fp_printf(fp, "\n");
-}
-
-void print_p_info(void)
-{
-    char fname[LINE_LENGTH];
-    FILE *fp;
-    int i, to_file, pext = (ext_info.id == EXTENDED);
-
-    if (print_only) {
-       fp = stdout;
-       to_file = TRUE;
-    } else {
-       mvaddstr(COMMAND_LINE_Y, COMMAND_LINE_X,
-                "Enter filename or press RETURN to display on screen: ");
-
-       if ((to_file = get_string(fname, LINE_LENGTH, NULL)) < 0)
-           return;
-
-       if (to_file) {
-           if ((fp = fopen(fname, "w")) == NULL) {
-               char errstr[LINE_LENGTH];
-               sprintf(errstr, PRINT_OPEN_ERR, fname);
-               print_warning(errstr);
-               return;
-           }
-       } else {
-           fp = NULL;
-           erase();
-           move(0, 0);
-       }
-    }
-
-    fp_printf(fp, "Partition Table for %s\n", disk_device);
-    fp_printf(fp, "\n");
-    fp_printf(fp, "           First    Last\n");
-    fp_printf(fp, " # Type    Sector   Sector   Offset  Length   Filesystem Type (ID)  Flags\n");
-    fp_printf(fp, "-- ------- -------- -------- ------- -------- --------------------- ---------\n");
-
-    for (i = 0; i < num_parts; i++) {
-       if (pext && (p_info[i].first_sector >= ext_info.first_sector)) {
-           print_p_info_entry(fp,&ext_info);
-           pext = FALSE;
-       }
-       print_p_info_entry(fp, &(p_info[i]));
-    }
-
-    if (to_file) {
-       if (!print_only)
-           fclose(fp);
-    } else {
-       mvaddstr(COMMAND_LINE_Y, COMMAND_LINE_X,
-                "Press any key to continue...");
-       clrtoeol();
-       refresh();
-       (void)getch();
-    }
-}
-
-void print_part_entry(FILE *fp, int num, partition_info *pi)
-{
-    int first = 0, start = 0, end = 0, size = 0;
-    int ss = 0, sh = 0, sc = 0;
-    int es = 0, eh = 0, ec = 0;
-    int flags = 0, id = 0;
-
-    if (pi != NULL) {
-       flags = pi->flags;
-       id = pi->id;
-
-       if (IS_LOGICAL(num))
-           first = pi->offset;
-       else
-           first = pi->first_sector + pi->offset;
-
-       start = pi->first_sector + pi->offset;
-       end = pi->last_sector;
-       size = end - start + 1;
-       if ((start/(sectors*heads)) > 1023)
-           start = heads*sectors*1024 - 1;
-       if ((end/(sectors*heads)) > 1023)
-           end = heads*sectors*1024 - 1;
-
-       ss = start % sectors + 1;
-       start /= sectors;
-       sh = start % heads;
-       sc = start / heads;
-
-       es = end % sectors + 1;
-       end /= sectors;
-       eh = end % heads;
-       ec = end / heads;
-    }
-
-    fp_printf(fp, "%2d  0x%02X %4d %4d %4d 0x%02X %4d %4d %4d %7d %7d\n",
-             num+1, flags, sh, ss, sc, id, eh, es, ec, first, size);
-}
-
-
-void print_part_table(void)
-{
-    int i, j, to_file;
-    char fname[LINE_LENGTH];
-    FILE *fp;
-
-    if (print_only) {
-       fp = stdout;
-       to_file = TRUE;
-    } else {
-       mvaddstr(COMMAND_LINE_Y, COMMAND_LINE_X,
-                "Enter filename or press RETURN to display on screen: ");
-
-       if ((to_file = get_string(fname, LINE_LENGTH, NULL)) < 0)
-           return;
-
-       if (to_file) {
-           if ((fp = fopen(fname, "w")) == NULL) {
-               char errstr[LINE_LENGTH];
-               sprintf(errstr, PRINT_OPEN_ERR, fname);
-               print_warning(errstr);
-               return;
-           }
-       } else {
-           fp = NULL;
-           erase();
-           move(0, 0);
-       }
-    }
-
-    fp_printf(fp, "Partition Table for %s\n", disk_device);
-    fp_printf(fp, "\n");
-    fp_printf(fp, "         ---Starting---      ----Ending---- Start   Number\n");
-    fp_printf(fp, " # Flags Head Sect Cyl   ID  Head Sect Cyl  Sector  Sectors\n");
-    fp_printf(fp, "-- ----- ---- ---- ---- ---- ---- ---- ---- ------- -------\n");
-
-    for (i = 0; i < 4; i++) {
-       for (j = 0;
-            j < num_parts && (p_info[j].id <= 0 || p_info[j].num != i);
-            j++);
-       if (j < num_parts) {
-           print_part_entry(fp, i, &(p_info[j]));
-       } else if (ext_info.id == EXTENDED && ext_info.num == i) {
-           print_part_entry(fp, i, &ext_info);
-       } else {
-           print_part_entry(fp, i, NULL);
-       }
-    }
-
-    for (i = 0; i < num_parts; i++)
-       if (IS_LOGICAL(p_info[i].num))
-           print_part_entry(fp, p_info[i].num, &(p_info[i]));
-
-    if (to_file) {
-       if (!print_only)
-           fclose(fp);
-    } else {
-       mvaddstr(COMMAND_LINE_Y, COMMAND_LINE_X,
-                "Press any key to continue...");
-       clrtoeol();
-       refresh();
-       (void)getch();
-    }
-}
-
-void print_tables(void)
-{
-    int done = FALSE;
-
-    mvaddstr(COMMAND_LINE_Y, COMMAND_LINE_X, "Print format [rst]: ");
-    clrtoeol();
-    refresh();
-
-    while (!done)
-       switch (toupper(getch())) {
-       case 'R':
-           print_raw_table();
-           done = TRUE;
-           break;
-       case 'S':
-           print_p_info();
-           done = TRUE;
-           break;
-       case 'T':
-           print_part_table();
-           done = TRUE;
-           break;
-       case ESC:
-           done = TRUE;
-           break;
-       }
-}
-
-#define END_OF_HELP "EOHS!"
-#define NEW_HELP_SCREEN "SNHS!"
-void display_help()
-{
-    char *help_text[] = {
-       "Help Screen for cfdisk " VERSION,
-       "",
-       "This is cfdisk, a curses based disk partitioning programs, which",
-       "allows you to create, delete and modify partitions on your hard",
-       "disk drive.",
-       "",
-       "Copyright (C) 1994 Kevin E. Martin",
-       "",
-       "Command      Meaning",
-       "-------      -------",
-       "  b          Toggle bootable flag of the current partition",
-       "  d          Delete the current partition",
-       "  g          Change cylinders, heads, sectors-per-track parameters",
-       "             WARNING: This option should only be used by people who",
-       "             know what they are doing.",
-       "  h          Print this screen",
-       "  m          Maximize disk usage of the current partition",
-       "             Note: This may make the partition incompatible with",
-       "             DOS, OS/2, ...",
-       "  n          Create new partition from free space",
-       "  p          Print partition table to the screen or to a file",
-       "             There are several different formats for the partition",
-       "             that you can choose from:",
-       "                r - Raw data (exactly what would be written to disk)",
-       "                s - Table ordered by sectors",
-       "                t - Table in raw format",
-       "  q          Quit program without writing partition table",
-       "  t          Change the filesystem type",
-       "  u          Change units of the partition size display",
-       "             Rotates through Mb, sectors and cylinders",
-       "  W          Write partition table to disk (must enter upper case W)",
-        "             Since this might destroy data on the disk, you must",
-       "             either confirm or deny the write by entering `yes' or",
-       "             `no'",
-       "Up Arrow     Move cursor to the previous partition",
-       "Down Arrow   Move cursor to the next partition",
-       "CTRL-L       Redraws the screen",
-       "  ?          Print this screen",
-       "",
-       "Note: All of the commands can be entered with either upper or lower",
-       "case letters (except for Writes).",
-       END_OF_HELP
-    };
-
-    int cur_line = 0;
-    FILE *fp = NULL;
-
-    erase();
-    move(0, 0);
-    while (strcmp(help_text[cur_line], END_OF_HELP))
-       if (!strcmp(help_text[cur_line], NEW_HELP_SCREEN)) {
-           mvaddstr(COMMAND_LINE_Y, COMMAND_LINE_X,
-                    "Press any key to continue...");
-           clrtoeol();
-           refresh();
-           (void)getch();
-           erase();
-           move(0, 0);
-           cur_line++;
-       } else
-           fp_printf(fp, "%s\n", help_text[cur_line++]);
-
-    mvaddstr(COMMAND_LINE_Y, COMMAND_LINE_X,
-            "Press any key to continue...");
-    clrtoeol();
-    refresh();
-    (void)getch();
-}
-
-int change_geometry(void)
-{
-    int ret_val = FALSE;
-    int done = FALSE;
-    char def[LINE_LENGTH];
-    char response[LINE_LENGTH];
-    int tmp_val;
-
-    while (!done) {
-       mvaddstr(COMMAND_LINE_Y, COMMAND_LINE_X,
-                "Change disk geometry information [chs]: ");
-       clrtoeol();
-       refresh();
-
-       clear_warning();
-
-       switch (toupper(getch())) {
-       case 'C':
-           sprintf(def, "%d", cylinders);
-           mvaddstr(COMMAND_LINE_Y, COMMAND_LINE_X,
-                    "Enter the number of cylinders: ");
-           if (get_string(response, LINE_LENGTH, def) > 0) {
-               tmp_val = atoi(response);
-               if (tmp_val > 0 && tmp_val <= MAX_CYLINDERS) {
-                   cylinders = tmp_val;
-                   ret_val = TRUE;
-               } else
-                   print_warning(BAD_CYLINDERS);
-           }
-           break;
-       case 'H':
-           sprintf(def, "%d", heads);
-           mvaddstr(COMMAND_LINE_Y, COMMAND_LINE_X,
-                    "Enter the number of heads: ");
-           if (get_string(response, LINE_LENGTH, def) > 0) {
-               tmp_val = atoi(response);
-               if (tmp_val > 0 && tmp_val <= MAX_HEADS) {
-                   heads = tmp_val;
-                   ret_val = TRUE;
-               } else
-                   print_warning(BAD_HEADS);
-           }
-           break;
-       case 'S':
-           sprintf(def, "%d", sectors);
-           mvaddstr(COMMAND_LINE_Y, COMMAND_LINE_X,
-                    "Enter the number of sectors per track: ");
-           if (get_string(response, LINE_LENGTH, def) > 0) {
-               tmp_val = atoi(response);
-               if (tmp_val > 0 && tmp_val <= MAX_SECTORS) {
-                   sectors = tmp_val;
-                   ret_val = TRUE;
-               } else
-                   print_warning(BAD_SECTORS);
-           }
-           break;
-       case ESC:
-       case CR:
-           done = TRUE;
-           break;
-       default:
-           putchar(BELL);
-           break;
-       }
-    }
-
-    if (ret_val) {
-       if (p_info[num_parts-1].last_sector > heads*sectors*cylinders-1) {
-           while (p_info[num_parts-1].first_sector > heads*sectors*cylinders-1) {
-               if (p_info[num_parts-1].id == FREE_SPACE ||
-                   p_info[num_parts-1].id == UNUSABLE)
-                   remove_part(num_parts-1);
-               else
-                   del_part(num_parts-1);
-           }
-
-           p_info[num_parts-1].last_sector = heads*sectors*cylinders - 1;
-
-           if (ext_info.last_sector > heads*sectors*cylinders-1)
-               ext_info.last_sector = heads*sectors*cylinders - 1;
-       } else if (p_info[num_parts-1].last_sector < heads*sectors*cylinders-1) {
-           if (p_info[num_parts-1].id == FREE_SPACE ||
-               p_info[num_parts-1].id == UNUSABLE) {
-               p_info[num_parts-1].last_sector = heads*sectors*cylinders - 1;
-           } else {
-               insert_part(num_parts, PRI_OR_LOG, FREE_SPACE, 0,
-                           p_info[num_parts-1].last_sector+1,
-                           heads*sectors*cylinders-1, 0);
-           }
-       }
-
-       /* Make sure the partitions are correct */
-       check_part_info();
-    }
-
-    return ret_val;
-}
-
-void change_id(int i)
-{
-    char id[LINE_LENGTH], def[LINE_LENGTH];
-    int num_types = 0;
-    int num_across, num_down;
-    int len, new_id = LINUX;
-    int y_start, y_end;
-    int j, pos;
-
-    for (num_types = 0, j = 1; j < NUM_PART_TYPES; j++)
-       if (partition_type[j])
-           num_types++;
-
-    num_across = COLS/COL_ID_WIDTH;
-    num_down = (((float)num_types)/num_across + 1);
-    y_start = COMMAND_LINE_Y - 1 - num_down;
-    if (y_start > DISK_TABLE_START+cur_part+4)
-       y_start = DISK_TABLE_START+cur_part+4;
-    y_end = y_start + num_down - 1;
-
-    for (j = y_start - 1; j <= y_end + 1; j++) {
-       move(j, 0);
-       clrtoeol();
-    }
-
-    for (pos = 0, j = 1; j < NUM_PART_TYPES; j++)
-       if (partition_type[j]) {
-           move(y_start + pos % num_down, (pos/num_down)*COL_ID_WIDTH + 1);
-           printw("%02X %-16.16s", j, partition_type[j]);
-           pos++;
-       }
-
-    sprintf(def, "%02X", new_id);
-    mvaddstr(COMMAND_LINE_Y, COMMAND_LINE_X, "Enter filesystem type: ");
-    if ((len = get_string(id, 2, def)) <= 0 && len != GS_DEFAULT)
-       return;
-
-    if (len != GS_DEFAULT) {
-       if (!isxdigit(id[0]))
-           return;
-       new_id = (isdigit(id[0]) ? id[0] - '0' : tolower(id[0]) - 'a' + 10);
-       if (len == 2)
-           if (isxdigit(id[1]))
-               new_id = new_id*16 +
-                   (isdigit(id[1]) ? id[1] - '0' : tolower(id[1]) - 'a' + 10);
-           else
-               return;
-    }
-
-    if (new_id == 0)
-       print_warning(ID_EMPTY);
-    else if (new_id == EXTENDED)
-       print_warning(ID_EXT);
-    else
-       p_info[i].id = new_id;
-}
-
-void draw_partition(int i)
-{
-    int size, j;
-    int y = i + DISK_TABLE_START + 2 - (cur_part/NUM_ON_SCREEN)*NUM_ON_SCREEN;
-
-    if (!arrow_cursor) {
-       move(y, 0);
-       for (j = 0; j < COLS; j++)
-           addch(' ');
-    }
-
-    if (p_info[i].id > 0) {
-       mvprintw(y, NAME_START,
-                "%s%d", disk_device, p_info[i].num+1);
-       if (p_info[i].flags) {
-           if (p_info[i].flags == ACTIVE_FLAG)
-               mvaddstr(y, FLAGS_START, "Boot");
-           else
-               mvprintw(y, FLAGS_START, "Unk(%02X)", p_info[i].flags);
-           if (p_info[i].first_sector == 0 || IS_LOGICAL(p_info[i].num)) {
-               if (p_info[i].offset != sectors)
-                   addstr(", NC");
-           } else {
-               if (p_info[i].offset != 0)
-                   addstr(", NC");
-           }
-       } else {
-           if (p_info[i].first_sector == 0 || IS_LOGICAL(p_info[i].num)) {
-               if (p_info[i].offset != sectors)
-                   mvaddstr(y, FLAGS_START, "NC");
-           } else {
-               if (p_info[i].offset != 0)
-                   mvaddstr(y, FLAGS_START, "NC");
-           }
-       }
-    }
-    mvaddstr(y, PTYPE_START,
-            (p_info[i].id == UNUSABLE ? "" :
-             (IS_LOGICAL(p_info[i].num) ? "Logical" :
-              (p_info[i].num >= 0 ? "Primary" :
-               (p_info[i].num == PRI_OR_LOG ? "Pri/Log" :
-                (p_info[i].num == PRIMARY ? "Primary" : "Logical"))))));
-    if (p_info[i].id == UNUSABLE)
-       mvaddstr(y, FSTYPE_START, "Unusable");
-    else if (p_info[i].id == FREE_SPACE)
-       mvaddstr(y, FSTYPE_START, "Free Space");
-    else if (partition_type[p_info[i].id])
-       mvaddstr(y, FSTYPE_START, partition_type[p_info[i].id]);
-    else
-       mvprintw(y, FSTYPE_START, "Unknown (%02X)", p_info[i].id);
-
-    size = p_info[i].last_sector - p_info[i].first_sector + 1;
-    if (display_units == SECTORS)
-       mvprintw(y, SIZE_START, "%9d", size);
-    else if (display_units == CYLINDERS)
-       mvprintw(y, SIZE_START, "%9d", size/(sectors*heads));
-    else
-       mvprintw(y, SIZE_START, "%9.2f", ceiling(size/20.48)/100);
-    if (((size/(sectors*heads)) != ceiling(size/(sectors*(float)heads))) ||
-       ((p_info[i].first_sector/(sectors*heads)) !=
-        ceiling(p_info[i].first_sector/(sectors*heads))))
-       mvprintw(y, COLUMNS-1, "*");
-}
-
-void init_const(void)
-{
-    if (!defined) {
-       NAME_START = (((float)NAME_START)/COLUMNS)*COLS;
-       FLAGS_START = (((float)FLAGS_START)/COLUMNS)*COLS;
-       PTYPE_START = (((float)PTYPE_START)/COLUMNS)*COLS;
-       FSTYPE_START = (((float)FSTYPE_START)/COLUMNS)*COLS;
-       SIZE_START = (((float)SIZE_START)/COLUMNS)*COLS;
-       COMMAND_LINE_X = (((float)COMMAND_LINE_X)/COLUMNS)*COLS;
-
-       COMMAND_LINE_Y = LINES - 4;
-       WARNING_START = LINES - 2;
-
-       if ((NUM_ON_SCREEN = COMMAND_LINE_Y - DISK_TABLE_START - 3) <= 0)
-           NUM_ON_SCREEN = 1;
-
-       COLUMNS = COLS;
-       defined = TRUE;
-    }
-}
-
-void draw_screen(void)
-{
-    int i;
-    char *line;
-
-    line = (char *)malloc((COLS+1)*sizeof(char));
-
-    if (warning_last_time) {
-       for (i = 0; i < COLS; i++) {
-           move(WARNING_START, i);
-           line[i] = inch();
-       }
-       line[COLS] = 0;
-    }
-
-    erase();
-
-    if (warning_last_time)
-       mvaddstr(WARNING_START, 0, line);
-
-
-    sprintf(line, "cfdisk %s", VERSION);
-    mvaddstr(HEADER_START, (COLS-strlen(line))/2, line);
-    sprintf(line, "Disk Drive: %s", disk_device);
-    mvaddstr(HEADER_START+2, (COLS-strlen(line))/2, line);
-    sprintf(line, "Heads: %d   Sectors per Track: %d   Cylinders: %d",
-           heads, sectors, cylinders);
-    mvaddstr(HEADER_START+3, (COLS-strlen(line))/2, line);
-
-    mvaddstr(DISK_TABLE_START, NAME_START, "Name");
-    mvaddstr(DISK_TABLE_START, FLAGS_START, "Flags");
-    mvaddstr(DISK_TABLE_START, PTYPE_START, "Part Type");
-    mvaddstr(DISK_TABLE_START, FSTYPE_START, "FS Type");
-    if (display_units == SECTORS)
-       mvaddstr(DISK_TABLE_START, SIZE_START, "  Sectors");
-    else if (display_units == CYLINDERS)
-       mvaddstr(DISK_TABLE_START, SIZE_START, "Cylinders");
-    else
-       mvaddstr(DISK_TABLE_START, SIZE_START, "Size (MB)");
-
-    move(DISK_TABLE_START+1, 1);
-    for (i = 1; i < COLS-1; i++)
-       addch('-');
-
-    if (NUM_ON_SCREEN >= num_parts)
-       for (i = 0; i < num_parts; i++)
-           draw_partition(i);
-    else
-       for (i = (cur_part/NUM_ON_SCREEN)*NUM_ON_SCREEN;
-            i < NUM_ON_SCREEN + (cur_part/NUM_ON_SCREEN)*NUM_ON_SCREEN &&
-            i < num_parts;
-            i++)
-           draw_partition(i);
-
-    free(line);
-}
-
-int draw_cursor(int move)
-{
-    if (move != 0 && (cur_part + move < 0 || cur_part + move >= num_parts))
-       return -1;
-
-    if (arrow_cursor)
-       mvaddstr(DISK_TABLE_START + cur_part + 2
-                - (cur_part/NUM_ON_SCREEN)*NUM_ON_SCREEN, 0, "   ");
-    else
-       draw_partition(cur_part);
-
-    cur_part += move;
-
-    if (((cur_part - move)/NUM_ON_SCREEN)*NUM_ON_SCREEN !=
-       (cur_part/NUM_ON_SCREEN)*NUM_ON_SCREEN)
-       draw_screen();
-
-    if (arrow_cursor)
-       mvaddstr(DISK_TABLE_START + cur_part + 2
-                - (cur_part/NUM_ON_SCREEN)*NUM_ON_SCREEN, 0, "-->");
-    else {
-       standout();
-       draw_partition(cur_part);
-       standend();
-    }
-
-    return 0;
-}
-
-void die(int dummy)
-{
-    signal(SIGINT, old_SIGINT);
-    signal(SIGTERM, old_SIGTERM);
-    mvcur(0, COLS-1, LINES-1, 0);
-    nl();
-    endwin();
-    fdexit(0);
-}
-
-void do_curses_fdisk(void)
-{
-    int done = FALSE;
-    char command;
-
-    initscr();
-    old_SIGINT = signal(SIGINT, die);
-    old_SIGTERM = signal(SIGTERM, die);
-#ifdef DEBUG
-    signal(SIGINT, old_SIGINT);
-    signal(SIGTERM, old_SIGTERM);
-#endif
-
-    cbreak();
-    noecho();
-    nonl();
-
-    init_const();
-
-    fill_p_info();
-
-    draw_screen();
-
-    while (!done) {
-       (void)draw_cursor(0);
-
-       if (p_info[cur_part].id == FREE_SPACE)
-           mvaddstr(COMMAND_LINE_Y, COMMAND_LINE_X, "Command [hnpquW?]: ");
-       else if (p_info[cur_part].id > 0)
-           mvaddstr(COMMAND_LINE_Y, COMMAND_LINE_X, "Command [bdhmpqtuW?]: ");
-       else
-           mvaddstr(COMMAND_LINE_Y, COMMAND_LINE_X, "Command [hpquW?]: ");
-
-       clrtoeol();
-       refresh();
-
-       clear_warning();
-
-       switch (command = getch()) {
-       case 'B':
-       case 'b':
-           if (p_info[cur_part].id > 0)
-               p_info[cur_part].flags ^= 0x80;
-           else
-               print_warning(NO_FLAGS);
-           break;
-       case 'D':
-       case 'd':
-           if (p_info[cur_part].id > 0) {
-               del_part(cur_part);
-               if (cur_part >= num_parts)
-                   cur_part = num_parts - 1;
-               draw_screen();
-           } else
-               print_warning(DEL_EMPTY);
-           break;
-       case 'G':
-       case 'g':
-           if (change_geometry())
-               draw_screen();
-           break;
-       case 'M':
-       case 'm':
-           if (p_info[cur_part].id > 0) {
-               if (p_info[cur_part].first_sector == 0 ||
-                   IS_LOGICAL(p_info[cur_part].num)) {
-                   if (p_info[cur_part].offset == sectors)
-                       p_info[cur_part].offset = 1;
-                   else
-                       p_info[cur_part].offset = sectors;
-                   draw_screen();
-               } else if (p_info[cur_part].offset != 0)
-                   p_info[cur_part].offset = 0;
-               else
-                   print_warning(MAX_UNMAXABLE);
-           } else
-               print_warning(MAX_UNMAXABLE);
-           break;
-       case 'N':
-       case 'n':
-           if (p_info[cur_part].id == FREE_SPACE) {
-               new_part(cur_part);
-               draw_screen();
-           } else if (p_info[cur_part].id == UNUSABLE)
-               print_warning(ADD_UNUSABLE);
-           else
-               print_warning(ADD_EXISTS);
-           break;
-       case 'P':
-       case 'p':
-           print_tables();
-           draw_screen();
-           break;
-       case 'Q':
-       case 'q':
-           done = TRUE;
-           break;
-       case 'T':
-       case 't':
-           if (p_info[cur_part].id > 0) {
-               change_id(cur_part);
-               draw_screen();
-           } else
-               print_warning(TYPE_EMPTY);
-           break;
-       case 'U':
-       case 'u':
-           if (display_units == MEGABYTES)
-               display_units = SECTORS;
-           else if (display_units == SECTORS)
-               display_units = CYLINDERS;
-           else if (display_units == CYLINDERS)
-               display_units = MEGABYTES;
-           draw_screen();
-           break;
-       case 'W':
-           write_part_table();
-           break;
-       case 'H':
-       case 'h':
-       case '?':
-           display_help();
-           draw_screen();
-           break;
-       case ESC:
-           if ((command = getch()) == '[') {
-               command = getch();
-               switch (command) {
-               case 'A' : /* Up arrow */
-                   if (!draw_cursor(-1))
-                       command = 0;
-                   else
-                       print_warning(NO_MORE_PARTS);
-                   break;
-               case 'B' : /* Down arrow */
-                   if (!draw_cursor(1))
-                       command = 0;
-                   else
-                       print_warning(NO_MORE_PARTS);
-                   break;
-               case 'C' : /* Right arrow */
-               case 'D' : /* Left arrow */
-               }
-           }
-           if (command)
-               putchar(BELL); /* CTRL-G */
-           break;
-       case REDRAWKEY:
-           clear();
-           draw_screen();
-           break;
-       default:
-           print_warning(BAD_COMMAND);
-           putchar(BELL); /* CTRL-G */
-       }
-    }
-
-    signal(SIGINT, old_SIGINT);
-    signal(SIGTERM, old_SIGTERM);
-    mvcur(0, COLS-1, LINES-1, 0);
-    nl();
-    endwin();
-    fdexit(0);
-}
-
-void copyright(void)
-{
-    fprintf(stderr, "Copyright (C) 1994 Kevin E. Martin\n");
-}
-
-void usage(char *prog_name)
-{
-    fprintf(stderr,
-           "%s: [-avz] [-c # cylinders] [-h # heads] [-s # sectors/track]\n",
-           prog_name);
-    fprintf(stderr,
-           "[ -P opt ] device\n");
-    copyright();
-}
-
-void main(int argc, char **argv)
-{
-    char c;
-    int i, len;
-
-    while ((c = getopt(argc, argv, "ac:h:s:vzP:")) != EOF)
-       switch (c) {
-       case 'a':
-           arrow_cursor = TRUE;
-           break;
-       case 'c':
-           cylinders = atoi(optarg);
-           if (cylinders <= 0 || cylinders > MAX_CYLINDERS) {
-               fprintf(stderr, "%s: %s\n", argv[0], BAD_CYLINDERS);
-               exit(1);
-           }
-           break;
-       case 'h':
-           heads = atoi(optarg);
-           if (heads <= 0 || heads > MAX_HEADS) {
-               fprintf(stderr, "%s: %s\n", argv[0], BAD_HEADS);
-               exit(1);
-           }
-           break;
-       case 's':
-           sectors = atoi(optarg);
-           if (sectors <= 0 || sectors > MAX_SECTORS) {
-               fprintf(stderr, "%s: %s\n", argv[0], BAD_SECTORS);
-               exit(1);
-           }
-           break;
-       case 'v':
-           fprintf(stderr, "cfdisk %s\n", VERSION);
-           copyright();
-           exit(0);
-       case 'z':
-           zero_table = TRUE;
-           break;
-       case 'P':
-           len = strlen(optarg);
-           for (i = 0; i < len; i++) {
-               switch (optarg[i]) {
-               case 'r':
-                   print_only |= PRINT_RAW_TABLE;
-                   break;
-               case 's':
-                   print_only |= PRINT_SECTOR_TABLE;
-                   break;
-               case 't':
-                   print_only |= PRINT_PARTITION_TABLE;
-                   break;
-               default:
-                   usage(argv[0]);
-                   break;
-               }
-           }
-           break;
-       default:
-           usage(argv[0]);
-           exit(1);
-       }
-
-    if (argc-optind == 1)
-       disk_device = argv[optind];
-    else if (argc-optind != 0) {
-       usage(argv[0]);
-       exit(1);
-    } else if ((fd = open(DEFAULT_DEVICE, O_RDWR)) < 0)
-       disk_device = ALTERNATE_DEVICE;
-    else close(fd);
-
-    if (print_only) {
-       fill_p_info();
-       if (print_only & PRINT_RAW_TABLE)
-           print_raw_table();
-       if (print_only & PRINT_SECTOR_TABLE)
-           print_p_info();
-       if (print_only & PRINT_PARTITION_TABLE)
-           print_part_table();
-    } else
-       do_curses_fdisk();
-}
index 46b9e23209b7f2f7ea797994f4b09290db21d2e0..7f792c5c9f9e45c8b65365663069a121e9adc4e0 100644 (file)
@@ -56,9 +56,19 @@ static void verify_disk(char *name)
     fflush(stdout);
     if ((fd = open(name,O_RDONLY)) < 0) PERROR(name);
     for (cyl = 0; cyl < param.track; cyl++) {
+       int read_bytes;
+
        printf("%3d\b\b\b",cyl);
        fflush(stdout);
-       if (read(fd,data,cyl_size) != cyl_size) PERROR("read");
+       read_bytes = read(fd,data,cyl_size);
+       if(read_bytes != cyl_size) {
+           if(read_bytes < 0)
+                   perror("Read: ");
+           fprintf(stderr,
+                   "Problem reading cylinder %d, expected %d, read %d\n",
+                   cyl, cyl_size, read_bytes);
+           exit(1);
+       }
        for (count = 0; count < cyl_size; count++)
            if (data[count] != FD_FILL_BYTE) {
                printf("bad data in cyl %d\nContinuing ... ",cyl);
index 2a59da01804a75a752670c0b3bb20d27b420958c..a9282e1e6936e5b02d8b97ab00d59e304a776b10 100644 (file)
@@ -24,3 +24,5 @@
 1680/1440      3360    21   2  80    0 0x0C 0x00 0xCF     0x6C # ?????
 
 # Add user-specific formats here
+cbm1581         1600    10   2  80    2 0x2A 0x02 0xDF     0x2E
+800/720         1600    10   2  80    0 0x2A 0x02 0xDF     0x2E
diff --git a/disk-utils/frag.8 b/disk-utils/frag.8
deleted file mode 100644 (file)
index c2f67b5..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-.\" Copyright 1992,1993,1994 Rickard E. Faith (faith@cs.unc.edu)
-.\" May be distributed under the GNU General Public License
-.TH FRAG 8 "8 January 1994" "Linux 0.99" "Linux Programmer's Manual"
-.SH NAME
-frag \- simple fragmentation checker
-.SH SYNOPSIS
-.B /usr/sbin/frag
-.B "[ \-s [ \-s ]]"
-filename ...
-.SH DESCRIPTION
-.B frag
-will report the file system fragmentation on a specified
-.IR filename .
-If the
-.I filename
-is a directory,
-.B frag
-will recursively descend the directory.
-.SH OPTIONS
-.TP
-.B \-s
-Silent (may be set to 1 or 2).  The first
-.B \-s
-eliminates the file by file statistics, and just prints the 
-examined directories and a summary.  The second
-.B \-s
-eliminates the printing of the directories, and just prints a
-summary.  This option is useful when
-.B frag
-is used on a directory.
-.SH "SEE ALSO"
-.BR mkfs (8),
-.BR fsck (8),
-.BR mkefs (8),
-.BR efsck (8)
-.SH BUGS
-.B frag
-will get caught in an infinite loop in the /proc filesystem.
-.SH AUTHORS
-V1.0 by Werner Almesberger
-.br
-V1.1 by Steffen Zahn, adding directory recursion
-.br
-V1.2 by Rob Hooft, adding hole counts
-.br
-V1.3 by Steffen Zahn, ignore symlinks,
-don't cross filesys borders, get filesystem block size at runtime
diff --git a/disk-utils/frag.c b/disk-utils/frag.c
deleted file mode 100644 (file)
index 0098e02..0000000
+++ /dev/null
@@ -1,311 +0,0 @@
-/* frag.c - simple fragmentation checker
-            V1.0 by Werner Almesberger
-            V1.1 by Steffen Zahn, adding directory recursion
-            V1.2 by Rob Hooft, adding hole counts
-            V1.3 by Steffen Zahn, email: szahn%masterix@emndev.siemens.co.at
-                    14 Nov 93
-                    - ignore symlinks,
-                    - don't cross filesys borders
-                    - get filesystem block size at runtime
-           V1.4 by Michael Bischoff <mbi@mo.math.nat.tu-bs.de> to handle
-                   indirect blocks better, but only for ext2fs
-                   (applied by faith@cs.unc.edu, Sat Feb  4 22:06:27 1995)
-
-            TODO: - handle hard links
- */
-
-#include <stdio.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <limits.h>
-#include <stdlib.h>
-#include <string.h>
-#include <dirent.h>
-#include <sys/stat.h>
-#include <sys/vfs.h>
-#include <linux/fs.h>                      /* for FIBMAP */
-
-typedef struct StackElem {
-    struct StackElem *backref, *next;
-    char name[NAME_MAX];
-    char dir_seen;
-    char from_cmd_line;
-} StackElem;
-
-StackElem *top = NULL;
-
-
-void discard( void )
-{
-    StackElem *se = top;
-    if( se == NULL )
-        return ;
-    top = se->next;
-    free(se);
-}
-
-void push( StackElem * se )
-{
-    se -> next = top;
-    top = se;
-}
-
-char *p2s( StackElem *se, char *path )
-{
-    char *s;
-    if( se->backref!=NULL ) {
-        path = p2s( se->backref, path );
-        if( path[-1]!='/' )
-            *path++ = '/';
-    }
-    s = se->name;
-    while( *s )
-        *path++ = *s++;
-    return path;
-}
-
-char *path2str( StackElem *se, char *path )
-{
-    *(p2s( se, path ))=0;
-    return path;
-}
-              
-void *xmalloc( size_t size )
-{
-    void *p;
-    if( (p=malloc(size))==NULL ) {
-        fprintf(stderr,"\nvirtual memory exhausted.\n");
-        exit(1);
-    }
-    return p;
-}
-
-int main(int argc,char **argv)
-{
-    int fd,last_phys_block,
-        fragments_in_file, blocks_in_file,
-        blocks,current_phys_block,
-        this_fragment, largest_fragment, i;
-    long sum_blocks=0, sum_frag_blocks=0, sum_files=0, sum_frag_files=0;
-    long num_hole=0, sum_hole=0, hole;
-    struct stat st;
-    struct statfs stfs;
-    StackElem *se, *se1;
-    char path[PATH_MAX], pathlink[PATH_MAX], *p;
-    DIR *dir;
-    struct dirent *de;
-    char silent_flag=0;
-    dev_t local_fs;
-    int block_size;
-    
-    if (argc < 2)
-    {
-        fprintf(stderr,"usage: %s [-s [-s]] filename ...\n",argv[0]);
-        exit(1);
-    }
-    argc--; argv++;
-    while (argc>0)
-    {
-        p = *argv;
-        if( *p=='-' )
-            while( *++p )
-                switch( *p )
-                {
-                case 's':
-                    silent_flag++; /* may be 1 or 2 */
-                    break;
-                default:
-                    fprintf(stderr,"\nunknown flag %c\n", *p );
-                    exit(1);
-                }
-        else
-        {
-            se = xmalloc( sizeof(StackElem) );
-            se->backref=NULL; se->dir_seen=0; se->from_cmd_line=1;
-            strcpy( se->name, p );
-            push(se);
-        }
-        argc--; argv++;
-    }
-    while ( top != NULL)
-    {
-        se = top;
-        if( se->dir_seen )
-            discard();
-        else
-        {
-            path2str( se, path );
-            if( readlink( path, pathlink, sizeof(pathlink) )>=0 )
-            {                   /* ignore symlinks */
-                if(silent_flag<1)
-                {
-                    printf("symlink %s\n", path );
-                }
-                discard();
-            }
-            else if( stat( path,&st) < 0)
-            {
-                perror( path );
-                discard();
-            }
-            else if( !se->from_cmd_line && (local_fs!=st.st_dev) )
-            {                   /* do not cross filesystem borders */
-                if(silent_flag<2)
-                {
-                    printf("different filesystem %s\n", path );
-                }
-                discard();
-            }
-            else
-            {
-                if( se->from_cmd_line )
-                {
-                    local_fs = st.st_dev;
-                    if ( statfs( path, &stfs )<0 )
-                    {
-                        perror( path );
-                        block_size = 1024;
-                    }
-                    else
-                        block_size = stfs.f_bsize;
-                }
-                if( S_ISREG(st.st_mode))   /* regular file */
-                {
-                    if ( (fd = open( path ,O_RDONLY)) < 0 )
-                    {
-                        perror( path );
-                        discard();
-                    }
-                    else
-                    {
-                        last_phys_block = -1;
-                        fragments_in_file = 0;
-                        hole = 0; this_fragment=0;
-                        largest_fragment=0;
-                        blocks_in_file = (st.st_size+block_size-1)/block_size;
-                        for (blocks = 0; blocks < blocks_in_file; blocks++)
-                        {
-                            current_phys_block = blocks;
-                            if (ioctl(fd,FIBMAP,&current_phys_block) < 0)
-                            {
-                                perror(path);
-                                break;
-                            }
-                            if (current_phys_block) { /* no hole here */
-                               int indirect;
-                               /* indirect is the number of indirection */
-                               /* blocks which must be skipped */
-                               indirect = 0;
-                               /* every 256 blocks there is an indirect block,
-                                  the first of these is before block 12 */
-                               if (blocks >= 12 && (blocks-12) % 256 == 0)
-                                   ++indirect;
-                               /* there is a block pointing to the indirect
-                                  blocks every 64K blocks */
-                               if (blocks >= 256+12 && (blocks-256-12) % 65536 == 0)
-                                   ++indirect; /* 2nd indirect block */
-                               /* there is a single triple indirect block */
-                               if (blocks == 65536 + 256 + 12)
-                                   ++indirect;
-                                if (last_phys_block == current_phys_block-1-indirect)
-                                    this_fragment++;
-                               else { /* start of first or new fragment */
-                                    if( largest_fragment<this_fragment )
-                                        largest_fragment=this_fragment;
-                                    this_fragment=1;
-                                    fragments_in_file++;
-                                }
-                                last_phys_block = current_phys_block;
-                            }
-                            else
-                            {
-                                hole++;
-                            }
-                        }
-                        if( largest_fragment<this_fragment )
-                            largest_fragment=this_fragment;
-                        blocks_in_file-=hole;
-                                /* number of allocated blocks in file */
-                        if( !silent_flag )
-                        {
-                            if( fragments_in_file < 2
-                                || blocks_in_file < 2 )
-                                i = 0; /* fragmentation 0 % */
-                            else
-                                i = (fragments_in_file - 1) * 100 /
-                                    (blocks_in_file-1);
-                                /* maximum fragmentation 100%
-                                   means every block is an fragment */
-                            printf(" %3d%%  %s  (%d block(s), %d fragment(s), largest %d",
-                                   i, path, blocks_in_file,
-                                   fragments_in_file,largest_fragment);
-                            if (hole)
-                            {
-                                printf(", %d hole(s))\n",hole);
-                            }
-                            else
-                            {
-                                printf(")\n");
-                            }
-                        }
-                        sum_blocks+=blocks_in_file;
-                        if (hole)
-                            num_hole++;
-                        sum_hole+=hole;
-                        sum_files++;
-                        if( fragments_in_file>1 )
-                        {
-                            sum_frag_blocks+=blocks_in_file-largest_fragment;
-                            sum_frag_files++;
-                        }
-                        discard();
-                        close(fd);
-                    }
-                }
-                else if( S_ISDIR( st.st_mode ) ) /* push dir contents */
-                {
-                    if( (dir=opendir( path ))==NULL )
-                    {
-                        perror(path);
-                        discard();
-                    }
-                    else
-                    {
-                        if( silent_flag<2 )
-                            printf("reading %s\n", path);
-                        while( (de=readdir(dir))!=NULL )
-                        {
-                            if( (strcmp(de->d_name,".")!=0)
-                                && (strcmp(de->d_name,"..")!=0) )
-                            {
-                                se1 = xmalloc( sizeof(StackElem) );
-                                se1->backref=se; se1->dir_seen=0;
-                                se1->from_cmd_line=0;
-                                strcpy( se1->name, de->d_name );
-                                push(se1);
-                            }
-                        }
-                        closedir( dir );
-                        se->dir_seen=1;
-                    }
-                }
-                else /* if( S_ISREG(st.st_mode)) */
-                    discard();
-            }
-        } /* if( se->dir_seen ) */
-    } /* while ( top != NULL) */
-    if (sum_files>1)
-    {
-        printf("\nsummary:\n");
-        printf(" %3ld%% file  fragmentation (%ld of %ld files contain fragments)\n",
-               sum_files<1 ? 0L : sum_frag_files*100/sum_files,
-               sum_frag_files, sum_files);
-        printf(" %3ld%% block fragmentation (%ld of %ld blocks are in fragments)\n",
-               sum_blocks<1 ? 0L : sum_frag_blocks*100/sum_blocks,
-               sum_frag_blocks, sum_blocks);
-        if (num_hole>1)
-            printf("  %ld files contain %ld blocks in holes\n",
-                   num_hole,sum_hole);
-    }
-    exit(0);
-}
index ae1d7b1a88c65128f1690cb98e7515693c3f0ea9..ba64bf34f2a2011dd51f5cfffd7b0e8b6234d853 100644 (file)
@@ -317,7 +317,7 @@ int check_zone_nr(unsigned short * nr, int * corrected)
        return 0;
 }
 
-
+#ifdef HAVE_MINIX2
 int check_zone_nr2 (unsigned int *nr, int *corrected)
 {
        if (!*nr)
@@ -336,6 +336,7 @@ int check_zone_nr2 (unsigned int *nr, int *corrected)
        }
        return 0;
 }
+#endif
 
 /*
  * read-block reads block nr into the buffer at addr.
@@ -627,11 +628,12 @@ struct minix_inode * get_inode(unsigned int nr)
                                nr);
                        print_current_name();
                        printf("'\n");
-                       if (repair)
+                       if (repair) {
                                if (ask("Mark in use",1))
                                        mark_inode(nr);
-                       else
+                       } else {
                                errors_uncorrected = 1;
+                       }
                }
                if (S_ISDIR(inode->i_mode))
                        directory++;
@@ -762,7 +764,7 @@ static int add_zone(unsigned short * znr, int * corrected)
        return block;
 }
 
-
+#ifdef HAVE_MINIX2
 static int add_zone2 (unsigned int *znr, int *corrected)
 {
        int result;
@@ -795,6 +797,7 @@ static int add_zone2 (unsigned int *znr, int *corrected)
                zone_count[block]--;
        return block;
 }
+#endif
 
 static void add_zone_ind(unsigned short * znr, int * corrected)
 {
@@ -812,7 +815,9 @@ static void add_zone_ind(unsigned short * znr, int * corrected)
                write_block(block, blk);
 }
 
-static void add_zone_ind2 (unsigned int *znr, int *corrected)
+#ifdef HAVE_MINIX2
+static void
+add_zone_ind2 (unsigned int *znr, int *corrected)
 {
        static char blk[BLOCK_SIZE];
        int i, chg_blk = 0;
@@ -827,6 +832,7 @@ static void add_zone_ind2 (unsigned int *znr, int *corrected)
        if (chg_blk)
                write_block (block, blk);
 }
+#endif
 
 static void add_zone_dind(unsigned short * znr, int * corrected)
 {
@@ -844,6 +850,7 @@ static void add_zone_dind(unsigned short * znr, int * corrected)
                write_block(block, blk);
 }
 
+#ifdef HAVE_MINIX2
 static void
 add_zone_dind2 (unsigned int *znr, int *corrected)
 {
@@ -877,6 +884,7 @@ add_zone_tind2 (unsigned int *znr, int *corrected)
        if (blk_chg)
                write_block (block, blk);
 }
+#endif
 
 void check_zones(unsigned int i)
 {
@@ -945,18 +953,20 @@ void check_file(struct minix_inode * dir, unsigned int offset)
        name_depth++;
        inode = get_inode(ino);
        name_depth--;
-       if (!offset)
+       if (!offset) {
                if (!inode || strcmp(".",name)) {
                        print_current_name();
                        printf(": bad directory: '.' isn't first\n");
                        errors_uncorrected = 1;
                } else return;
-       if (offset == dirsize)
+       }
+       if (offset == dirsize) {
                if (!inode || strcmp("..",name)) {
                        print_current_name();
                        printf(": bad directory: '..' isn't second\n");
                        errors_uncorrected = 1;
                } else return;
+       }
        if (!inode)
                return;
        if (name_depth < MAX_DEPTH)
@@ -1230,12 +1240,12 @@ int main(int argc, char ** argv)
 #endif
        while (argc-- > 1) {
                argv++;
-               if (argv[0][0] != '-')
+               if (argv[0][0] != '-') {
                        if (device_name)
                                usage();
                        else
                                device_name = argv[0];
-               else while (*++argv[0])
+               else while (*++argv[0])
                        switch (argv[0][0]) {
                                case 'l': list=1; break;
                                case 'a': automatic=1; repair=1; break;
index 57132a483a62dc30534402e7aa5fb5087217659e..2dd616484bfc29a27b91b7e208e7c41aa96ca8fe 100644 (file)
@@ -55,13 +55,8 @@ This is really only useful for testing.
 .TP
 .BI -t \ fstype
 Specifies the type of file system to be built.
-If not specified, the type is deduced by searching for
-.I filesys
-in
-.I /etc/fstab
-and using the corresponding entry.
-If the type can not be deduced, the default file system type
-(currently minix) is used.
+If not specified, the default file system type
+(currently ext2) is used.
 .TP
 .B fs-options
 File system-specific options to be passed to the real file 
index db7aefaeab63c2bbaca2f6954efbf53e0fc48804..c34da53264c8bee6d6e9019a6fe52e6b707be68e 100644 (file)
@@ -624,7 +624,7 @@ int main(int argc, char ** argv)
 #endif
   while (argc-- > 1) {
     argv++;
-    if (argv[0][0] != '-')
+    if (argv[0][0] != '-') {
       if (device_name) {
        BLOCKS = strtol(argv[0],&tmp,0);
        if (*tmp) {
@@ -634,7 +634,7 @@ int main(int argc, char ** argv)
        }
       } else
        device_name = argv[0];
-    else { 
+    else { 
       if(argv[0][1] == 'l') {
        listfile = argv[1];
        argv++;
index 1e14167b8c69c628e2ab2830a7cf534dbe08dbd8..2df606c57aad5c4215dfb47e47b8fbe8294f72b5 100644 (file)
@@ -1,83 +1,93 @@
-.\" Copyright 1992, 1993 Rickard E. Faith (faith@cs.unc.edu)
+.\" Copyright 1998 Andries E. Brouwer (aeb@cwi.nl)
+.\"
 .\" May be distributed under the GNU General Public License
-.\" Modified with suggestions from Linus, Mon Feb  1 21:40:49 1993
-.\" Modified with patches from Kai, Wed Jun 22 21:54:56 1994
-.\" Patches from jaggy@purplet.demon.co.uk (Mike Jagdis), Wed Feb 8 1995
-.\" Added comments from Nick Holloway, Sat Feb 11 1995, faith@cs.unc.edu
-.\" "
-.TH MKSWAP 8 "February 1995" "Linux 1.0" "Linux Programmer's Manual"
+.\" Rewritten for 2.1.117, aeb, 981010.
+.\"
+.TH MKSWAP 8 "1 December 1998" "Linux 2.1.117" "Linux Programmer's Manual"
 .SH NAME
 mkswap \- set up a Linux swap area
 .SH SYNOPSIS
-.B "mkswap [ \-c ]"
-.IB device  " [" size-in-blocks "]"
+.BI "mkswap [\-c] [\-v" N "] [\-f] " device  " [" size "]"
 .SH DESCRIPTION
 .B mkswap
 sets up a Linux swap area on a device or in a file.
 
+(After creating the swap area, you need the
+.B swapon
+command to start using it. Usually swap areas are listed in
+.I /etc/fstab
+so that they can be taken into use at boot time by a
+.B swapon -a
+command in some boot script.)
+
 The
 .I device
-is usually of the following form:
-
-.nf
-.RS
-/dev/hda[1-8]
-/dev/hdb[1-8]
-/dev/sda[1-8]
-/dev/sdb[1-8]
-.RE
-.fi
+argument will usually be a disk partition (something like
+.I /dev/hda4
+or
+.IR /dev/sdb7 )
+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.
 
 The
-.I size-in-blocks
-parameter is the desired size of the file system, in blocks.  This
-information is determined automatically by
+.I size
+parameter is superfluous but retained for backwards compatibility.
+(It specifies the desired size of the swap area in 1024-byte blocks.
 .B mkswap
-if it is omitted.  Block counts are rounded down so that the total
-size is an integer multiple of the machine's page size.  Only block
-counts in the range MINCOUNT..MAXCOUNT are allowed.  If the block count
-exceeds the MAXCOUNT, it is truncated to that value and a warning
-message is issued.
+will use the entire partition or file if it is omitted.)
 
-The MINCOUNT and MAXCOUNT values for a swap area are:
+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
+signature.
 
-.RS
-MINCOUNT = 10 * PAGE_SIZE / 1024
-.br
-MAXCOUNT = (PAGE_SIZE - 10) * 8 * PAGE_SIZE / 1024
-.RE
+In the old style, the rest of this first page was a bit map,
+with a 1 bit for each usable page of the swap area.
+Since the first page holds this bit map, the first bit is 0.
+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.
+On an alpha and sparc64, with S=8192, the useful area is at most
+535560992 bytes (almost 512 MB with the same proviso).
 
-For example, on a machine with 4kB pages (e.g., x86), we get:
+The old setup wastes most of this bitmap page, because zero bits
+denote bad blocks or blocks past the end of the swap space,
+and a simple integer suffices to indicate the size of the swap space,
+while the bad blocks, if any, can simply be listed. Nobody wants
+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 is now (2^31 - 2*S) bytes,
+roughly 2 GB.
 
-.RS
-MINCOUNT = 10 * 4096 / 1024 = 40
-.br
-MAXCOUNT = (4096 - 10) * 8 * 4096 / 1024 = 130752
-.RE
+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.
 
-As each block is 1kB large, the swap area in this example could have a
-size that is anywhere in the range from 40kB up to 127.6875MB.
+Presently, Linux allows 8 swap areas. The areas in use can be seen
+in the file
+.I /proc/swaps
+(since 2.1.25).
 
-If you don't know the page size that your machine uses, you may be
-able to look it up with "cat /proc/cpuinfo".
+.B mkswap
+refuses areas smaller than 10 pages.
 
-The reason for the limit on MAXCOUNT is that a single page is used to
-hold the swap bitmap at the start of the swap area, where each bit
-represents a single page.  The reason for the -10, is that the
-signature is "SWAP-SPACE" -- 10 characters.
+If you don't know the page size that your machine uses, you may be
+able to look it up with "cat /proc/cpuinfo" (or you may not -
+the contents of this file depend on architecture and kernel version).
 
 To setup a swap file, it is necessary to create that file before
 running
-.B mkswap .
-A sequence of commands similar to the following is reasonable for this
-purpose:
+.B mkswap ,
+e.g. using a command like
 
 .nf
 .RS
-# dd if=/dev/zero of=swapfile bs=1024 count=8192
-# mkswap swapfile 8192
-# sync
-# swapon swapfile
+# dd if=/dev/zero of=swapfile bs=1024 count=65536
 .RE
 .fi
 
@@ -88,19 +98,34 @@ to create the file is not acceptable).
 .SH OPTIONS
 .TP
 .B \-c
-Check the device for bad blocks before creating the file system.  If any
-are found, the count is printed.  This option is meant to be used for swap
-partitions
-.BR only ,
-and should
-.B not
-be used for regular files!  To make sure that regular files do not contain
-bad blocks, the partition that contains the regular file should have been
-created with
-.BR "mkfs -c" .
+Check the device (if it is a block device) for bad blocks
+before creating the swap area.
+If any are found, the count is printed.
+.TP
+.B \-f
+On SPARC, force creation of the swap area.
+Without this option
+.B mkswap
+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
+.B \-v0
+Create an old style swap area.
+.TP
+.B \-v1
+Create a new style swap area.
+
+.LP
+If no \-v option is given,
+.B mkswap
+will default to old style if the size of the swap area does not
+exceed the maximum size of an old style swap area, and also if
+the current kernel is older than 2.1.117 (and also if PAGE_SIZE
+is less than 2048).
+The new style header does not touch the first block, so may be
+preferable (also if the swap area is small), in case you have
+a boot loader or disk label there.
+
 .SH "SEE ALSO"
-.BR fsck (8),
-.BR mkfs (8),
-.BR fdisk (8)
-.SH AUTHOR
-Linus Torvalds (torvalds@cs.helsinki.fi)
+.BR fdisk (8),
+.BR swapon (8)
index 49447f2afc09a4a8121b26a5573fa15bde60a226..b3402366c7bdd6bc754bc2cc317654fadce60d33 100644 (file)
@@ -8,15 +8,21 @@
 /*
  * 20.12.91  - time began. Got VM working yesterday by doing this by hand.
  *
- * Usuage: mkswap [-c] device [size-in-blocks]
+ * Usuage: mkswap [-c] [-vN] [-f] device [size-in-blocks]
  *
- *     -c for readablility checking (use it unless you are SURE!)
+ *     -c   for readability checking. (Use it unless you are SURE!)
+ *     -vN  for swap areas version N. (Only N=0,1 known today.)
+ *      -f   for forcing swap creation even if it would smash partition table.
  *
- * The device may be a block device or a image of one, but this isn't
+ * The device may be a block device or an image of one, but this isn't
  * enforced (but it's not much fun on a character device :-).
  *
  * Patches from jaggy@purplet.demon.co.uk (Mike Jagdis) to make the
  * size-in-blocks parameter optional added Wed Feb  8 10:33:43 1995.
+ *
+ * Version 1 swap area code (for kernel 2.1.117), aeb, 981010.
+ *
+ * Sparc fixes, jj@ultra.linux.cz (Jakub Jelinek), 981201 - mangled by aeb.
  */
 
 #include <stdio.h>
 #include <string.h>
 #include <fcntl.h>
 #include <stdlib.h>
-#include <sys/ioctl.h>
+#include <sys/ioctl.h>         /* for _IO */
+#include <sys/utsname.h>
 #include <sys/stat.h>
-#include <asm/page.h>
+#include <asm/page.h>          /* for PAGE_SIZE and PAGE_SHIFT */
 
+#ifndef _IO
+/* pre-1.3.45 */
 #define BLKGETSIZE 0x1260
-
-#ifndef __linux__
-# define volatile
+#else
+/* same on i386, m68k, arm; different on alpha, mips, sparc, ppc */
+#define BLKGETSIZE _IO(0x12,96)
 #endif
 
-#define TEST_BUFFER_PAGES 8
-
 static char * program_name = "mkswap";
 static char * device_name = NULL;
 static int DEV = -1;
 static long PAGES = 0;
 static int check = 0;
 static int badpages = 0;
+static int version = -1;
+
+#define MAKE_VERSION(p,q,r)    (65536*(p) + 256*(q) + (r))
+
+static int
+linux_version_code(void) {
+       struct utsname my_utsname;
+       int p, q, r;
+
+       if (uname(&my_utsname) == 0) {
+               p = atoi(strtok(my_utsname.release, "."));
+               q = atoi(strtok(NULL, "."));
+               r = atoi(strtok(NULL, "."));
+               return MAKE_VERSION(p,q,r);
+       }
+       return 0;
+}
+
+/*
+ * 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().
+ */
+
+static int pagesize;
+static int *signature_page;
 
-static int signature_page[PAGE_SIZE/sizeof(int)];
+struct swap_header_v1 {
+        char         bootbits[1024];    /* Space for disklabel etc. */
+       unsigned int version;
+       unsigned int last_page;
+       unsigned int nr_badpages;
+       unsigned int padding[125];
+       unsigned int badpages[1];
+} *p;
+
+static void
+init_signature_page() {
+       pagesize = getpagesize();
+
+#ifdef PAGE_SIZE
+       if (pagesize != PAGE_SIZE)
+               fprintf(stderr, "Assuming pages of size %d\n", pagesize);
+#endif
+       signature_page = (int *) malloc(pagesize);
+       memset(signature_page,0,pagesize);
+       p = (struct swap_header_v1 *) signature_page;
+}
+
+static void
+write_signature(char *sig) {
+       char *sp = (char *) signature_page;
+
+       strncpy(sp+pagesize-10, sig, 10);
+}
+
+#define V0_MAX_PAGES   (8 * (pagesize - 10))
+#define V1_MAX_PAGES   ((0x7fffffff / pagesize) - 1)
+
+#define MAX_BADPAGES   ((pagesize-1024-128*sizeof(int)-10)/sizeof(int))
 
 static void bit_set (unsigned int *addr, unsigned int nr)
 {
@@ -66,41 +131,56 @@ static int bit_test_and_clear (unsigned int *addr, unsigned int nr)
        return (r & m) != 0;
 }
 
-/*
- * Volatile to let gcc know that this doesn't return. When trying
- * to compile this under minix, volatile gives a warning, as
- * exit() isn't defined as volatile under minix.
- */
-volatile void fatal_error(const char * fmt_string)
+void fatal_error(const char * fmt_string)
 {
        fprintf(stderr,fmt_string,program_name,device_name);
        exit(1);
 }
 
-#define usage() fatal_error("Usage: %s [-c] /dev/name [blocks]\n")
+#define usage() fatal_error("Usage: %s [-c] [-v0|-v1] /dev/name [blocks]\n")
 #define die(str) fatal_error("%s: " str "\n")
 
-void check_blocks(void)
-{
+void
+page_ok(int page) {
+       if (version==0)
+               bit_set(signature_page, page);
+}
+
+void
+page_bad(int page) {
+       if (version == 0)
+               bit_test_and_clear(signature_page, page);
+       else {
+               if (badpages == MAX_BADPAGES)
+                       die("too many bad pages");
+               p->badpages[badpages] = page;
+       }
+       badpages++;
+}
+
+void
+check_blocks(void) {
        unsigned int current_page;
        int do_seek = 1;
-       static char buffer[PAGE_SIZE];
+       char *buffer;
 
+       buffer = malloc(pagesize);
+       if (!buffer)
+               die("Out of memory");
        current_page = 0;
        while (current_page < PAGES) {
                if (!check) {
-                       bit_set(signature_page,current_page++);
+                       page_ok(current_page++);
                        continue;
                }
-               if (do_seek && lseek(DEV,current_page*PAGE_SIZE,SEEK_SET) !=
-               current_page*PAGE_SIZE)
+               if (do_seek && lseek(DEV,current_page*pagesize,SEEK_SET) !=
+                   current_page*pagesize)
                        die("seek failed in check_blocks");
-               if ((do_seek = (PAGE_SIZE != read(DEV, buffer, PAGE_SIZE)))) {
-                       bit_test_and_clear(signature_page,current_page++);
-                       badpages++;
+               if ((do_seek = (pagesize != read(DEV, buffer, pagesize)))) {
+                       page_bad(current_page++);
                        continue;
                }
-               bit_set(signature_page,current_page++);
+               page_ok(current_page++);
        }
        if (badpages)
                printf("%d bad page%s\n",badpages,(badpages>1)?"s":"");
@@ -117,12 +197,13 @@ static long valid_offset (int fd, int offset)
        return 1;
 }
 
-static int count_blocks (int fd)
+static int
+find_size (int fd)
 {
-       int high, low;
+       unsigned int high, low;
 
        low = 0;
-       for (high = 1; valid_offset (fd, high); high *= 2)
+       for (high = 1; high > 0 && valid_offset (fd, high); high *= 2)
                low = high;
        while (low < high - 1)
        {
@@ -133,26 +214,27 @@ static int count_blocks (int fd)
                else
                        high = mid;
        }
-       valid_offset (fd, 0);
        return (low + 1);
 }
 
-static int get_size(const char  *file)
+/* return size in pages, to avoid integer overflow */
+static int
+get_size(const char  *file)
 {
        int     fd;
        int     size;
 
-       fd = open(file, O_RDWR);
+       fd = open(file, O_RDONLY);
        if (fd < 0) {
                perror(file);
                exit(1);
        }
        if (ioctl(fd, BLKGETSIZE, &size) >= 0) {
-               close(fd);
-               return (size * 512);
+               int sectors_per_page = pagesize/512;
+               size /= sectors_per_page;
+       } else {
+               size = find_size(fd) / pagesize;
        }
-               
-       size = count_blocks(fd);
        close(fd);
        return size;
 }
@@ -161,28 +243,41 @@ int main(int argc, char ** argv)
 {
        char * tmp;
        struct stat statbuf;
+       int maxpages;
        int goodpages;
+       int offset;
+       int force = 0;
 
-       memset(signature_page,0,PAGE_SIZE);
        if (argc && *argv)
                program_name = *argv;
+
+       init_signature_page();  /* get pagesize */
+
        while (argc-- > 1) {
                argv++;
-               if (argv[0][0] != '-')
+               if (argv[0][0] != '-') {
                        if (device_name) {
-                               PAGES = strtol(argv[0],&tmp,0)>>(PAGE_SHIFT-10);
+                               int blocks_per_page = pagesize/1024;
+                               PAGES = strtol(argv[0],&tmp,0)/blocks_per_page;
                                if (*tmp)
                                        usage();
                        } else
                                device_name = argv[0];
-               else while (*++argv[0])
-                       switch (argv[0][0]) {
-                               case 'c': check=1; break;
-                               default: usage();
+               } else {
+                       switch (argv[0][1]) {
+                               case 'c':
+                                       check=1;
+                                       break;
+                               case 'f':
+                                       force=1;
+                                       break;
+                               case 'v':
+                                       version=atoi(argv[0]+2);
+                                       break;
+                               default:
+                                       usage();
                        }
-       }
-       if (device_name && !PAGES) {
-               PAGES = get_size(device_name) / PAGE_SIZE;
+               }
        }
        if (!device_name) {
                fprintf(stderr,
@@ -190,17 +285,38 @@ int main(int argc, char ** argv)
                        program_name);
                usage();
        }
+       if (!PAGES) {
+               PAGES = get_size(device_name);
+       }
+
+       if (version == -1) {
+               if (PAGES <= V0_MAX_PAGES)
+                       version = 0;
+               else if (linux_version_code() < MAKE_VERSION(2,1,117))
+                       version = 0;
+               else if (pagesize < 2048)
+                       version = 0;
+               else
+                       version = 1;
+       }
+       if (version != 0 && version != 1) {
+               fprintf(stderr, "%s: error: unknown version %d\n",
+                       program_name, version);
+               usage();
+       }
        if (PAGES < 10) {
                fprintf(stderr,
                        "%s: error: swap area needs to be at least %ldkB\n",
-                       program_name, (long)(10 * PAGE_SIZE / 1024));
+                       program_name, (long)(10 * pagesize / 1024));
                usage();
        }
-       if (PAGES > 8 * (PAGE_SIZE - 10)) {
-               PAGES = 8 * (PAGE_SIZE - 10);
+       maxpages = ((version == 0) ? V0_MAX_PAGES : V1_MAX_PAGES);
+       if (PAGES > maxpages) {
+               PAGES = maxpages;
                fprintf(stderr, "%s: warning: truncating swap area to %ldkB\n",
-                       program_name, PAGES * PAGE_SIZE / 1024);
+                       program_name, PAGES * pagesize / 1024);
        }
+
        DEV = open(device_name,O_RDWR);
        if (DEV < 0 || fstat(DEV, &statbuf) < 0) {
                perror(device_name);
@@ -210,19 +326,56 @@ int main(int argc, char ** argv)
                check=0;
        else if (statbuf.st_rdev == 0x0300 || statbuf.st_rdev == 0x0340)
                die("Will not try to make swapdevice on '%s'");
-       check_blocks();
-       if (!bit_test_and_clear(signature_page,0))
+
+#ifdef __sparc__
+       if (!force && version == 0) {
+               /* Don't overwrite partition table unless forced */
+               unsigned char *buffer = (unsigned char *)signature_page;
+               unsigned short *q, sum;
+
+               if (read(DEV, buffer, 512) != 512)
+                       die("fatal: first page unreadable");
+               if (buffer[508] == 0xDA && buffer[509] == 0xBE) {
+                       q = (unsigned short *)(buffer + 510);
+                       for (sum = 0; q >= (unsigned short *) buffer;)
+                               sum ^= *q--;
+                       if (!sum) {
+                               fprintf(stderr, "\
+%s: Device '%s' contains a valid Sun disklabel.\n\
+This probably means creating v0 swap would destroy your partition table\n\
+No swap created. If you really want to create swap v0 on that device, use\n\
+the -f option to force it.\n",
+                                       program_name, device_name);
+                               exit(1);
+                       }
+               }
+       }
+#endif
+
+       if (version == 0 || check)
+               check_blocks();
+       if (version == 0 && !bit_test_and_clear(signature_page,0))
                die("fatal: first page unreadable");
+       if (version == 1) {
+               p->version = version;
+               p->last_page = PAGES-1;
+               p->nr_badpages = badpages;
+       }
+
        goodpages = PAGES - badpages - 1;
        if (goodpages <= 0)
                die("Unable to set up swap-space: unreadable");
-       printf("Setting up swapspace, size = %ld bytes\n",
-               (long)(goodpages*PAGE_SIZE));
-       strncpy((char*)signature_page+PAGE_SIZE-10, "SWAP-SPACE", 10);
-       if (lseek(DEV, 0, SEEK_SET))
+       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");
-       if (PAGE_SIZE != write(DEV, signature_page, PAGE_SIZE))
+       if (write(DEV,(char*)signature_page+offset, pagesize-offset)
+           != pagesize-offset)
                die("unable to write signature page");
+
        /*
         * A subsequent swapon() will fail if the signature
         * is not actually on disk. (This is a kernel bug.)
index fee55300dd99049d08402ee3cb99b184a10c4b27..62234f3ac548f4b50030b350a6105b0fe4ce9384 100644 (file)
@@ -103,7 +103,7 @@ gap rate spec1 fmt_gap\n",name);
     exit(1);
 }
 
-void
+int
 main(int argc,char **argv)
 {
     int fd;
@@ -153,4 +153,5 @@ main(int argc,char **argv)
     else
        find_params(cmd,fd,argv[2]);
     /* not reached */
+    return 0;
 }
diff --git a/example.files/filesystems b/example.files/filesystems
new file mode 100644 (file)
index 0000000..74e1b51
--- /dev/null
@@ -0,0 +1,19 @@
+       ext2
+       vfat
+       umsdos
+       msdos
+       iso9660
+       minix
+       ntfs
+       hpfs
+       ufs
+       sysv
+       romfs
+       reiserfs
+nodev  autofs
+nodev  proc
+nodev  smbfs
+nodev  nfs
+nodev  coda
+nodev  devpts
+nodev  devfs
diff --git a/example.files/issue0 b/example.files/issue0
new file mode 100644 (file)
index 0000000..285f71a
--- /dev/null
@@ -0,0 +1 @@
+This is \n (\s \m \r) \d
diff --git a/example.files/syslog.conf b/example.files/syslog.conf
deleted file mode 100644 (file)
index 66e436b..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-kern.*                                                 /var/adm/kernlog
-mark.info;daemon.notice;mail.crit                      /var/adm/syslog
-mail.info;mail.debug                                   /var/adm/maillog
-daemon.info                                            /var/adm/daemon
-lpr.info                                               /var/adm/lpd-errs
-auth.notice                                            /var/adm/authlog
-*.err                                                  /var/adm/syslog
-*.notice;auth.debug                                    /var/adm/sysdebug
-*.alert                                                        /dev/console
-news.alert;news.crit;news.err                          /var/adm/news
-news.warning;news.notice                               /var/adm/news
-news.info;news.debug                                   /var/adm/news
diff --git a/example.files/syslog.conf.alt b/example.files/syslog.conf.alt
deleted file mode 100644 (file)
index c5923c4..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-# Log all kernel messages to the console.
-# Logging much else clutters up the screen.
-kern.*                                                 /dev/console
-#kern.*                                                        /dev/cua1
-
-# Log anything (except mail) of level info or higher.
-# Don't log private authentication messages!
-*.info;mail.none;authpriv.none                         /var/adm/messages
-
-# The authpriv file has restricted access.
-authpriv.*                                             /var/adm/secure
-
-# Log all the mail messages in one place.
-mail.*                                                 /var/adm/maillog
-
-# Everybody gets emergency messages, plus log them on another
-# machine.
-*.emerg                                                        *
-
-# Save mail and news errors of level err and higher in a
-# special file.
-uucp,news.crit                                         /var/adm/spooler
diff --git a/fdisk/Makefile b/fdisk/Makefile
new file mode 100644 (file)
index 0000000..e5415ac
--- /dev/null
@@ -0,0 +1,68 @@
+# 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 ../MCONFIG
+
+MAN8=
+SBIN=
+
+ifneq "$(CPU)" "sparc"
+# fsck and mkfs will compile, but there is no kernel support on sparc
+ifneq "$(CPU)" "m68k"
+MAN8:=$(MAN8) fdisk.8 cfdisk.8 sfdisk.8
+SBIN:=$(SBIN) fdisk cfdisk sfdisk
+endif
+else
+MAN8:=$(MAN8) fdisk.8
+SBIN:=$(SBIN) fdisk
+endif
+
+all: $(SBIN)
+
+cfdisk.o: cfdisk.c
+ifeq "$(HAVE_SLANG)" "yes"
+       $(CC) -c $(CFLAGS) -DSLCURSES=1 $< -o $@
+else
+ifeq "$(HAVE_NCURSES)" "yes"
+       $(CC) -c $(CFLAGS) $< -o $@
+else
+       :
+endif
+endif
+
+cfdisk: cfdisk.o llseek.o
+ifeq "$(HAVE_SLANG)" "yes"
+       $(CC) $(LDFLAGS) $^ -o $@ $(LIBSLANG)
+else
+ifeq "$(HAVE_NCURSES)" "yes"
+       $(CC) $(LDFLAGS) $^ -o $@ $(LIBCURSES) -lm
+else
+       @echo $@ not made since it requires ncurses or slang
+endif
+endif
+
+# not installed by default
+activate: sfdisk
+       rm -f activate
+       ln -s sfdisk activate
+
+fdisk: fdisk.o llseek.o fdiskbsdlabel.o fdisksgilabel.o fdisksunlabel.o \
+       fdiskaixlabel.o
+fdisk.o: fdisk.c fdisk.h
+fdiskbsdlabel.o: fdiskbsdlabel.c fdisk.h fdiskbsdlabel.h
+fdisksunlabel.o: fdisksunlabel.c fdisksunlabel.h fdisk.h
+fdiskaixlabel.o: fdiskaixlabel.c fdiskaixlabel.h fdisk.h
+sfdisk: sfdisk.o
+
+install: all
+       $(INSTALLDIR) $(SBINDIR)
+       $(INSTALLBIN) $(SBIN) $(SBINDIR)
+       $(INSTALLDIR) $(MAN8DIR)
+       $(INSTALLMAN) $(MAN8) $(MAN8DIR)
+
+.PHONY:        clean
+clean:
+       -rm -f *.o *~ core $(SBIN)
similarity index 100%
rename from disk-utils/README.cfdisk
rename to fdisk/README.cfdisk
similarity index 99%
rename from disk-utils/README.fdisk
rename to fdisk/README.fdisk
index 40f54b4b9fcdb606836767821a9be97946385d6a..86b182525d5c07978c161a9ad7fe83da794758cd 100644 (file)
@@ -577,3 +577,7 @@ Verify command before writing any changes to disk.
 
 If you set the disk geometry (tracks per cylinder, or sectors per
 track) to an incorrect value, you may lose all data on your disk.
+
+Do create BSD/SUN and/or IRIX/SGI disk labels only when you are sure
+that you want them.  Both features are intended to allow you READing
+those labels and prevent unintentional formatting of these disks.
similarity index 98%
rename from disk-utils/cfdisk.8
rename to fdisk/cfdisk.8
index c7ac94171b3fabcbecb42069eb2151f78455e7da..c8391af2a7f29f1ffcad374cd639296def3401b5 100644 (file)
@@ -395,9 +395,12 @@ Prints the partition table in specified formats.
 can be one or more of "r", "s" or "t".  See the
 .BR p rint
 command (above) for more information on the print formats.
+.SH "EXIT STATUS"
+0: No errors; 1: Invocation error; 2: I/O error;
+3: cannot get geometry; 4: bad partition table on disk.
 .SH "SEE ALSO"
 fdisk(8)
 .SH BUGS
-The current version does not support multiple disks (future addition).
+The current version does not support multiple disks.
 .SH AUTHOR
 Kevin E. Martin (martin@cs.unc.edu)
similarity index 92%
rename from disk-utils/cfdisk.c
rename to fdisk/cfdisk.c
index f0b5482f1f8a0ee5823a30512b33ca6fb431e789..96ddbbf24703eef5ac05c0d08ded99aa84f58c44 100644 (file)
  * >2GB patches: Sat Feb 11 09:08:10 1995, faith@cs.unc.edu
  * Prettier menus: Sat Feb 11 09:08:25 1995, Janne Kukonlehto
  *                                           <jtklehto@stekt.oulu.fi>
- * Versions 0.8e-l: aeb@cwi.nl
+ * Versions 0.8e-n: aeb@cwi.nl
  *  Recognition of NTFS / HPFS difference inspired by patches
  *  from Marty Leisner <leisner@sdsp.mc.xerox.com>
+ *  Exit codes by Enrique Zanardi <ezanardi@ull.es>:
+ *     0: all went well
+ *     1: command line error
+ *     2: hardware problems [BAD_SEEK, BAD_READ, BAD_WRITE or BAD_OPEN].
+ *     3: ioctl(fd, HDIO_GETGEO,...) failed [BAD_GEOMETRY].
+ *     4: bad partition table on disk. [BAD_PRIMARY or BAD_LOGICAL].
  *
  ****************************************************************************/
 
@@ -59,7 +65,6 @@
 #include <sys/stat.h>
 #include <sys/ioctl.h>
 #include <linux/types.h>
-#include <linux/genhd.h>
 #include <linux/hdreg.h>
 #include <linux/fs.h>          /* for BLKRRPART */
 
@@ -72,7 +77,7 @@ typedef long      ext2_loff_t;
 extern ext2_loff_t ext2_llseek(unsigned int fd, ext2_loff_t offset,
                               unsigned int origin);
 
-#define VERSION "0.8l"
+#define VERSION "0.8n"
 
 #define DEFAULT_DEVICE "/dev/hda"
 #define ALTERNATE_DEVICE "/dev/sda"
@@ -87,7 +92,8 @@ extern ext2_loff_t ext2_llseek(unsigned int fd, ext2_loff_t offset,
 #define MAX_SECTORS 63
 
 #define ACTIVE_FLAG 0x80
-#define PART_TABLE_FLAG 0xAA55
+#define PART_TABLE_FLAG0 0x55
+#define PART_TABLE_FLAG1 0xAA
 
 #define UNUSABLE -1
 #define FREE_SPACE     0x00
@@ -129,6 +135,7 @@ extern ext2_loff_t ext2_llseek(unsigned int fd, ext2_loff_t offset,
 #define YES_WRITE "Wrote partition table to disk"
 #define NO_WRITE "Did not write partition table to disk"
 #define RRPART_FAILED "Wrote partition table, but re-read table failed.  Reboot to update table."
+#define NOT_DOS_MBR_BOOTABLE "Not precisely one primary partition is bootable. DOS MBR cannot boot this."
 
 #define PRI_OR_LOG -1
 #define PRIMARY -2
@@ -179,6 +186,55 @@ extern ext2_loff_t ext2_llseek(unsigned int fd, ext2_loff_t offset,
    || (x) == 7 || (x) == 0xb || (x) == 0xc || (x) == 0xe \
    || (x) == 0x11 || (x) == 0x14 || (x) == 0x16 || (x) == 0x17)
 
+struct partition {
+        unsigned char boot_ind;         /* 0x80 - active */
+        unsigned char head;             /* starting head */
+        unsigned char sector;           /* starting sector */
+        unsigned char cyl;              /* starting cylinder */
+        unsigned char sys_ind;          /* What partition type */
+        unsigned char end_head;         /* end head */
+        unsigned char end_sector;       /* end sector */
+        unsigned char end_cyl;          /* end cylinder */
+        unsigned char start4[4];        /* starting sector counting from 0 */
+        unsigned char size4[4];         /* nr of sectors in partition */
+};
+
+/* start_sect and nr_sects are stored little endian on all machines */
+/* moreover, they are not aligned correctly */
+void
+store4_little_endian(unsigned char *cp, unsigned int val) {
+       cp[0] = (val & 0xff);
+       cp[1] = ((val >> 8) & 0xff);
+       cp[2] = ((val >> 16) & 0xff);
+       cp[3] = ((val >> 24) & 0xff);
+}
+
+unsigned int
+read4_little_endian(unsigned char *cp) {
+       return (uint)(cp[0]) + ((uint)(cp[1]) << 8)
+               + ((uint)(cp[2]) << 16) + ((uint)(cp[3]) << 24);
+}
+
+void
+set_start_sect(struct partition *p, unsigned int start_sect) {
+       store4_little_endian(p->start4, start_sect);
+}
+
+unsigned int
+get_start_sect(struct partition *p) {
+       return read4_little_endian(p->start4);
+}
+
+void
+set_nr_sects(struct partition *p, unsigned int nr_sects) {
+       store4_little_endian(p->size4, nr_sects);
+}
+
+unsigned int
+get_nr_sects(struct partition *p) {
+       return read4_little_endian(p->size4);
+}
+
 #define ALIGNMENT 2
 typedef union {
     struct {
@@ -189,7 +245,7 @@ typedef union {
        unsigned char align[ALIGNMENT];
        unsigned char buffer[0x1BE];
        struct partition part[4];
-       unsigned short flag;
+       unsigned char magicflag[2];
     } p;
 } partition_table;
 
@@ -280,6 +336,7 @@ char *partition_type[NUM_PART_TYPES] = {
     [0x16]        = "Hidden DOS FAT16 (big)",
     [0x17]        = "Hidden OS/2 HPFS or NTFS",
     [0x40]        = "Venix 80286",
+    [0x41]       = "PPC PReP boot",
     [0x51]        = "Novell?",
     [0x52]        = "Microport",
     [0x63]        = "GNU HURD",
@@ -298,6 +355,7 @@ char *partition_type[NUM_PART_TYPES] = {
     [0xDB]        = "CP/M",
     [0xE1]        = "DOS access",
     [0xE3]        = "DOS R/O",
+    [0xEB]       = "BeOS fs",
     [0xF2]        = "DOS secondary",
     [0xFF]        = "BBT"
 };
@@ -438,7 +496,7 @@ void print_warning(char *s)
 
 void die_x(int ret);
 
-void fatal(char *s)
+void fatal(char *s, int ret)
 {
     char str[LINE_LENGTH];
 
@@ -450,10 +508,10 @@ void fatal(char *s)
         putchar(BELL); /* CTRL-G */
         refresh();
         (void)getch();
-        die_x(1);
+        die_x(ret);
     } else {
         fprintf(stderr, "FATAL ERROR: %s\n", s);
-        exit(1);
+        exit(ret);
     }
 }
 
@@ -481,17 +539,17 @@ void die_x(int ret)
 void read_sector(char *buffer, int sect_num)
 {
     if (ext2_llseek(fd, ((ext2_loff_t) sect_num)*SECTOR_SIZE, SEEK_SET) < 0)
-       fatal(BAD_SEEK);
+       fatal(BAD_SEEK, 2);
     if (read(fd, buffer, SECTOR_SIZE) != SECTOR_SIZE)
-       fatal(BAD_READ);
+       fatal(BAD_READ, 2);
 }
 
 void write_sector(char *buffer, int sect_num)
 {
     if (ext2_llseek(fd, ((ext2_loff_t) sect_num)*SECTOR_SIZE, SEEK_SET) < 0)
-       fatal(BAD_SEEK);
+       fatal(BAD_SEEK, 2);
     if (write(fd, buffer, SECTOR_SIZE) != SECTOR_SIZE)
-       fatal(BAD_WRITE);
+       fatal(BAD_WRITE, 2);
 }
 
 void dos_copy_to_info(char *to, int tosz, char *from, int fromsz) {
@@ -565,7 +623,7 @@ void check_part_info(void)
            pri++;
        else if (p_info[i].id > 0 && IS_LOGICAL(p_info[i].num))
            log++;
-    if (is_extended(ext_info.id))
+    if (is_extended(ext_info.id)) {
        if (log > 0)
            pri++;
        else {
@@ -576,11 +634,12 @@ void check_part_info(void)
            ext_info.id = FREE_SPACE;
            ext_info.num = PRIMARY;
        }
+    }
 
     if (pri >= 4) {
        for (i = 0; i < num_parts; i++)
-           if (p_info[i].id == FREE_SPACE || p_info[i].id == UNUSABLE)
-               if (is_extended(ext_info.id))
+           if (p_info[i].id == FREE_SPACE || p_info[i].id == UNUSABLE) {
+               if (is_extended(ext_info.id)) {
                    if (p_info[i].first_sector >= ext_info.first_sector &&
                        p_info[i].last_sector <= ext_info.last_sector) {
                        p_info[i].id = FREE_SPACE;
@@ -601,16 +660,16 @@ void check_part_info(void)
                        p_info[i].num = LOGICAL;
                    } else
                        p_info[i].id = UNUSABLE;
-               else /* if (!is_extended(ext_info.id)) */
+               else /* if (!is_extended(ext_info.id)) */
                    p_info[i].id = UNUSABLE;
-           else /* if (p_info[i].id > 0) */
+           else /* if (p_info[i].id > 0) */
                while (0); /* Leave these alone */
     } else { /* if (pri < 4) */
        for (i = 0; i < num_parts; i++) {
            if (p_info[i].id == UNUSABLE)
                p_info[i].id = FREE_SPACE;
-           if (p_info[i].id == FREE_SPACE)
-               if (is_extended(ext_info.id))
+           if (p_info[i].id == FREE_SPACE) {
+               if (is_extended(ext_info.id)) {
                    if (p_info[i].first_sector >= ext_info.first_sector &&
                        p_info[i].last_sector <= ext_info.last_sector)
                        p_info[i].num = LOGICAL;
@@ -628,9 +687,9 @@ void check_part_info(void)
                        p_info[i].num = PRI_OR_LOG;
                    else
                        p_info[i].num = PRIMARY;
-               else /* if (!is_extended(ext_info.id)) */
+               else /* if (!is_extended(ext_info.id)) */
                    p_info[i].num = PRI_OR_LOG;
-           else /* if (p_info[i].id > 0) */
+           else /* if (p_info[i].id > 0) */
                while (0); /* Leave these alone */
        }
     }
@@ -742,11 +801,12 @@ int add_part(int num, int id, int flags, int first, int last, int offset,
     if (is_extended(ext_info.id) && log > 0)
        pri++;
 
-    if (IS_PRIMARY(num))
+    if (IS_PRIMARY(num)) {
        if (pri >= 4) {
            return -1;          /* no room for more */
        } else
            pri++;
+    }
 
     for (i = 0; i < num_parts && p_info[i].last_sector < first; i++);
 
@@ -902,15 +962,18 @@ void inc_logical(int i)
 
 struct MenuItem
 {
-    char key; /* Keyboard shortcut; if zero, then there is no more items in the menu item table */
+    int key; /* Keyboard shortcut; if zero, then there is no more items in the menu item table */
     char *name; /* Item name, should be eight characters with current implementation */
     char *desc; /* Item description to be printed when item is selected */
 };
 
-/* Actual function which prints the button bar and highlights the active button *
- * Should not be called directly. Call function menuSelect instead.             */
+/*
+ * Actual function which prints the button bar and highlights the active button
+ * Should not be called directly. Call function menuSelect instead.
+ */
 
-int menuUpdate( int y, int x, struct MenuItem *menuItems, int itemLength, char *available, int menuType, int current )
+int menuUpdate( int y, int x, struct MenuItem *menuItems, int itemLength,
+               char *available, int menuType, int current )
 {
     int i, lmargin = x, ymargin = y;
     /* Print available buttons */
@@ -925,7 +988,8 @@ int menuUpdate( int y, int x, struct MenuItem *menuItems, int itemLength, char *
             i++;
         }
         if( !menuItems[i].key ) break; /* No more menu items */
-        /* If selected item is not available and we have bypassed it, make current item selected */
+        /* If selected item is not available and we have bypassed it,
+          make current item selected */
         if( current < i && menuItems[current].key < 0 ) current = i;
         /* If current item is selected, highlight it */
         if( current == i ) /*attron( A_REVERSE )*/ standout ();
@@ -965,7 +1029,9 @@ int menuUpdate( int y, int x, struct MenuItem *menuItems, int itemLength, char *
         }
     }
     /* Print the description of selected item */
-    mvaddstr( WARNING_START + 1, (COLUMNS - strlen( menuItems[current].desc )) / 2, menuItems[current].desc );
+    mvaddstr( WARNING_START + 1,
+             (COLUMNS - strlen( menuItems[current].desc )) / 2,
+             menuItems[current].desc );
     return y;
 }
 
@@ -1085,7 +1151,8 @@ int menuSelect( int y, int x, struct MenuItem *menuItems, int itemLength, char *
         /* Should all keys to be accepted? */
         if( key && (menuType & MENU_ACCEPT_OTHERS) ) break;
         /* Is pressed key among acceptable ones */
-        if( key && (strchr(available, tolower(key)) || strchr(available, key)) ) break;
+        if( key && (strchr(available, tolower(key)) || strchr(available, key)))
+           break;
         /* The key has not been accepted so far -> let's reject it */
         if( key )
         {
@@ -1268,14 +1335,15 @@ void clear_p_info(void)
 
 void fill_p_info(void)
 {
-    int p, i;
+    int pn, i, bs, bsz;
+    struct partition *p;
     struct hd_geometry geometry;
     partition_table buffer;
     partition_info tmp_ext = { 0, 0, 0, 0, FREE_SPACE, PRIMARY };
 
     if ((fd = open(disk_device, O_RDWR)) < 0) {
         if ((fd = open(disk_device, O_RDONLY)) < 0)
-             fatal(BAD_OPEN);
+             fatal(BAD_OPEN, 2);
         opentype = O_RDONLY;
         print_warning(READONLY_WARN);
         if (curses_started) {
@@ -1307,7 +1375,7 @@ void fill_p_info(void)
     }
 
     if (!heads || !sectors || !cylinders)
-       fatal(BAD_GEOMETRY);    /* probably a file or cdrom */
+       fatal(BAD_GEOMETRY, 3); /* probably a file or cdrom */
 
     read_sector(buffer.c.b, 0);
 
@@ -1315,18 +1383,17 @@ void fill_p_info(void)
 
     if (!zero_table) {
        for (i = 0; i < 4; i++) {
-           int bs = buffer.p.part[i].start_sect;
+           p = & buffer.p.part[i];
+           bs = get_start_sect(p);
+           bsz = get_nr_sects(p);
 
-           if (buffer.p.part[i].sys_ind > 0 &&
-               add_part(i,
-                        buffer.p.part[i].sys_ind,
-                        buffer.p.part[i].boot_ind,
+           if (p->sys_ind > 0 &&
+               add_part(i, p->sys_ind, p->boot_ind,
                         ((bs <= sectors) ? 0 : bs),
-                        buffer.p.part[i].start_sect +
-                        buffer.p.part[i].nr_sects - 1,
+                        bs + bsz - 1,
                         ((bs <= sectors) ? bs : 0),
                         1)) {
-               fatal(BAD_PRIMARY);
+               fatal(BAD_PRIMARY, 4);
            }
            if (is_extended(buffer.p.part[i].sys_ind))
                tmp_ext = ext_info;
@@ -1339,32 +1406,34 @@ void fill_p_info(void)
            read_sector(buffer.c.b, logical_sectors[logical++]);
            i = 4;
            do {
-               for (p = 0;
-                    p < 4 && (!buffer.p.part[p].sys_ind ||
-                              is_extended(buffer.p.part[p].sys_ind));
-                    p++);
-
-               if (p < 4 && add_part(i++,
-                            buffer.p.part[p].sys_ind,
-                            buffer.p.part[p].boot_ind,
+               for (pn = 0;
+                    pn < 4 && (!buffer.p.part[pn].sys_ind ||
+                              is_extended(buffer.p.part[pn].sys_ind));
+                    pn++);
+
+               if (pn < 4) {
+                       p = & buffer.p.part[pn];
+                       bs = get_start_sect(p);
+                       bsz = get_nr_sects(p);
+
+                       if (add_part(i++, p->sys_ind, p->boot_ind,
                             logical_sectors[logical-1],
-                            logical_sectors[logical-1] +
-                            buffer.p.part[p].start_sect +
-                            buffer.p.part[p].nr_sects - 1,
-                            buffer.p.part[p].start_sect,
-                            1)) {
-                   fatal(BAD_LOGICAL);
+                            logical_sectors[logical-1] + bs + bsz - 1,
+                            bs, 1))
+                               fatal(BAD_LOGICAL, 4);
                }
 
-               for (p = 0;
-                    p < 4 && !is_extended(buffer.p.part[p].sys_ind);
-                    p++);
-               if (p < 4) {
-                   logical_sectors[logical] = ext_info.first_sector
-                        + ext_info.offset + buffer.p.part[p].start_sect;
-                   read_sector(buffer.c.b, logical_sectors[logical++]);
+               for (pn = 0;
+                    pn < 4 && !is_extended(buffer.p.part[pn].sys_ind);
+                    pn++);
+               if (pn < 4) {
+                       p = & buffer.p.part[pn];
+                       bs = get_start_sect(p);
+                       logical_sectors[logical] = ext_info.first_sector
+                               + ext_info.offset + bs;
+                       read_sector(buffer.c.b, logical_sectors[logical++]);
                }
-           } while (p < 4 && logical < MAXIMUM_PARTS-4);
+           } while (pn < 4 && logical < MAXIMUM_PARTS-4);
        }
     }
 }
@@ -1376,10 +1445,10 @@ void fill_part_table(struct partition *p, partition_info *pi)
     p->boot_ind = pi->flags;
     p->sys_ind = pi->id;
     if (IS_LOGICAL(pi->num))
-       p->start_sect = pi->offset;
+       set_start_sect(p,pi->offset);
     else
-       p->start_sect = pi->first_sector + pi->offset;
-    p->nr_sects = pi->last_sector - (pi->first_sector+pi->offset) + 1;
+       set_start_sect(p,pi->first_sector + pi->offset);
+    set_nr_sects(p, pi->last_sector - (pi->first_sector+pi->offset) + 1);
     sects = (((pi->first_sector+pi->offset)/(sectors*heads) > 1023) ?
             heads*sectors*1024 - 1 : pi->first_sector+pi->offset);
     set_hsc(p->head, p->sector, p->cyl, sects);
@@ -1403,7 +1472,8 @@ void fill_primary_table(partition_table *buffer)
     if (is_extended(ext_info.id))
        fill_part_table(&(buffer->p.part[ext_info.num]), &ext_info);
 
-    buffer->p.flag = PART_TABLE_FLAG;
+    buffer->p.magicflag[0] = PART_TABLE_FLAG0;
+    buffer->p.magicflag[1] = PART_TABLE_FLAG1;
 }
 
 void fill_logical_table(partition_table *buffer, partition_info *pi)
@@ -1412,7 +1482,8 @@ void fill_logical_table(partition_table *buffer, partition_info *pi)
     int i, sects;
 
     for (i = 0; i < logical && pi->first_sector != logical_sectors[i]; i++);
-    if (i == logical || buffer->p.flag != (unsigned short)PART_TABLE_FLAG)
+    if (i == logical || buffer->p.magicflag[0] != PART_TABLE_FLAG0
+                    || buffer->p.magicflag[1] != PART_TABLE_FLAG1)
        for (i = 0; i < SECTOR_SIZE; i++)
            buffer->c.b[i] = 0;
 
@@ -1432,8 +1503,8 @@ void fill_logical_table(partition_table *buffer, partition_info *pi)
 
        p->boot_ind = 0;
        p->sys_ind = DOS_EXTENDED;
-       p->start_sect = pi->first_sector - ext_info.first_sector - ext_info.offset;
-       p->nr_sects = pi->last_sector - pi->first_sector + 1;
+       set_start_sect(p, pi->first_sector - ext_info.first_sector - ext_info.offset);
+       set_nr_sects(p, pi->last_sector - pi->first_sector + 1);
        sects = ((pi->first_sector/(sectors*heads) > 1023) ?
                 heads*sectors*1024 - 1 : pi->first_sector);
        set_hsc(p->head, p->sector, p->cyl, sects);
@@ -1442,12 +1513,13 @@ void fill_logical_table(partition_table *buffer, partition_info *pi)
        set_hsc(p->end_head, p->end_sector, p->end_cyl, sects);
     }
 
-    buffer->p.flag = PART_TABLE_FLAG;
+    buffer->p.magicflag[0] = PART_TABLE_FLAG0;
+    buffer->p.magicflag[1] = PART_TABLE_FLAG1;
 }
 
 void write_part_table(void)
 {
-    int i, done = FALSE, len;
+    int i, ct, done = FALSE, len;
     partition_table buffer;
     struct stat s;
     int is_bdev;
@@ -1521,6 +1593,14 @@ void write_part_table(void)
              print_warning(RRPART_FAILED);
     } else
         print_warning(YES_WRITE);
+
+    /* Check: unique bootable primary partition? */
+    ct = 0;
+    for (i = 0; i < num_parts; i++)
+       if (IS_PRIMARY(i) && p_info[i].flags == ACTIVE_FLAG)
+           ct++;
+    if (ct != 1)
+       print_warning(NOT_DOS_MBR_BOOTABLE);
 }
 
 void fp_printf(FILE *fp, char *format, ...)
@@ -2049,7 +2129,7 @@ void change_id(int i)
     char id[LINE_LENGTH], def[LINE_LENGTH];
     int num_types = 0;
     int num_across, num_down;
-    int len, new_id = LINUX;
+    int len, new_id = ((p_info[i].id == LINUX) ? LINUX_SWAP : LINUX);
     int y_start, y_end;
     int j, pos;
 
@@ -2085,12 +2165,13 @@ void change_id(int i)
        if (!isxdigit(id[0]))
            return;
        new_id = (isdigit(id[0]) ? id[0] - '0' : tolower(id[0]) - 'a' + 10);
-       if (len == 2)
+       if (len == 2) {
            if (isxdigit(id[1]))
                new_id = new_id*16 +
                    (isdigit(id[1]) ? id[1] - '0' : tolower(id[1]) - 'a' + 10);
            else
                return;
+       }
     }
 
     if (new_id == 0)
@@ -2472,9 +2553,10 @@ Options:
     copyright();
 }
 
-int main(int argc, char **argv)
+int
+main(int argc, char **argv)
 {
-    char c;
+    int c;
     int i, len;
 
     setlocale(LC_CTYPE, "");
similarity index 89%
rename from disk-utils/fdisk.8
rename to fdisk/fdisk.8
index 576bce2ec2186ea738de1bce3d2181b91a06dcad..6307b98ec207acb29bdaa4424cbcc6bd3c93a6bd 100644 (file)
@@ -5,9 +5,9 @@
 .SH NAME
 fdisk \- Partition table manipulator for Linux
 .SH SYNOPSIS
-.BI "fdisk [\-b] [\-u] [" device ]
+.BI "fdisk [\-u] [" device ]
 .sp
-.BI "fdisk \-l [\-b] [\-u] [" "device ..." ]
+.BI "fdisk \-l [\-u] [" "device ..." ]
 .sp
 .BI "fdisk \-s " "partition ..."
 .sp
@@ -74,6 +74,17 @@ Do not start a partition that actually uses its first sector
 (like a swap partition) at cylinder 0, since that will
 destroy the disklabel.
 
+An IRIX/SGI type disklabel can describe 16 partitions,
+the eleventh of which should be an entire `volume' partition,
+while the ninth should be labeled `volume header'.
+The volume header will also cover the partition table, i.e.,
+it starts at block zero and extends by default over five cylinders.
+The remaining space in the volume header may be used by header
+directory entries.  No partitions may overlap with the volume header.
+Also do not change its type and make some file system on it, since
+you will lose the partition table.  Use this type of label only when
+working with Linux on IRIX/SGI machines or IRIX/SGI disks under Linux.
+
 A DOS type partition table can describe an unlimited number
 of partitions. In sector 0 there is room for the description
 of 4 partitions (called `primary'). One of these may be an
@@ -170,13 +181,6 @@ List the partition tables for
 .BR /dev/ed[a-d] ,
 and then exit.
 .TP
-.B \-b
-When listing partition tables, also output a `Begin' column,
-as earlier versions of fdisk did by default.
-(Note: the values in this column, when given in cylinder units,
-cannot be larger than 1023. There is nothing wrong if Begin and Start
-differ, at least not as far as Linux is concerned.)
-.TP
 .B \-u
 When listing partition tables, give sizes in sectors instead
 of cylinders.
@@ -206,8 +210,14 @@ Try them in the order
 .BR cfdisk ,
 .BR fdisk ,
 .BR sfdisk .
+.PP
+The IRIX/SGI type disklabel is currently not supported by the kernel.
+Moreover, IRIX/SGI header directories are not fully supported yet.
+.PP
+The option `dump partition table to file' is missing.
 .\" .SH AUTHORS
 .\" A. V. Le Blanc (LeBlanc@mcc.ac.uk)
 .\" Bernhard Fastenrath (fasten@informatik.uni-bonn.de)
 .\" Jakub Jelinek (jj@sunsite.mff.cuni.cz)
+.\" Andreas Neuper (ANeuper@GUUG.de)
 .\" and many others.
similarity index 78%
rename from disk-utils/fdisk.c
rename to fdisk/fdisk.c
index d99a8b45223cc47bea0f0d26204376592b4b556b..8cdc6df84482201e0f43c9779c1eb5fb07fff58d 100644 (file)
@@ -49,6 +49,8 @@
  * Tue Sep 26 17:07:54 1995: More patches from aeb.  Fix segfaults, all >4GB.
  *   Don't destroy random data if extd partition starts past 4GB, aeb, 950818.
  *   Don't segfault on bad partition created by previous fdisk.
+ * Fixed for using variable blocksizes (needed by magnet-optical drive-patch)
+ *   (from orschaer@cip.informatik.uni-erlangen.de)
  * Modified, Fri Jul 14 11:13:35 MET DST 1996, jj@sunsite.mff.cuni.cz:
  *      editor for Sun disklabels.
  * Modified, Wed Jul  3 10:14:17 MET DST 1996, jj@sunsite.mff.cuni.cz:
@@ -61,6 +63,9 @@
  *   [cfdisk on the other hand is nice and correct]
  * Try to avoid reading a CD-ROM.
  * Do not print Begin column -- it confuses too many people -- aeb, 980610.
+ * Modified, Sat Oct  3 14:40:17 MET DST 1998, ANeuper@GUUG.de
+ *     Support SGI's partitioning -- an, 980930.
+ * Do the verify using LBA, not CHS, limits -- aeb, 981206.
  */
 
 
 #include <linux/fs.h>          /* for BLKRRPART, BLKGETSIZE */
 
 #include "fdisk.h"
-#if defined(sparc)
+
 #include "fdisksunlabel.h"
-#endif
+#include "fdisksgilabel.h"
+#include "fdiskaixlabel.h"
+
+#include "../version.h"
 
 #define hex_val(c)     ({ \
                                char _c = (c); \
                        })
 
 
-#define VERSION        "2.8"           /* util-linux version */
-
 #define DEFAULT_DEVICE "/dev/hda"
 #define ALTERNATE_DEVICE "/dev/sda"
 #define LINE_LENGTH    80
 #define sector(s)      ((s) & 0x3f)
 #define cylinder(s, c) ((c) | (((s) & 0xc0) << 2))
 
-#define calculate(h,s,c) (sector(s) - 1 + sectors * \
+#define hsc2sector(h,s,c) (sector(s) - 1 + sectors * \
                                ((h) + heads * cylinder(s,c)))
 #define set_hsc(h,s,c,sector) { \
                                s = sector % sectors + 1;       \
@@ -166,18 +172,6 @@ get_nr_sects(struct partition *p) {
        return read4_little_endian(p->size4);
 }
 
-#define ACTIVE_FLAG    0x80
-
-#define EXTENDED       0x05
-#define WIN98_EXTENDED  0x0f
-#define LINUX_PARTITION        0x81
-#define LINUX_SWAP     0x82
-#define LINUX_NATIVE   0x83
-#define LINUX_EXTENDED 0x85
-
-#define IS_EXTENDED(i) \
-       ((i) == EXTENDED || (i) == WIN98_EXTENDED || (i) == LINUX_EXTENDED)
-
 /* normally O_RDWR, -l option gives O_RDONLY */
 static int type_open = O_RDWR;
 
@@ -185,7 +179,7 @@ char        *disk_device = DEFAULT_DEVICE,  /* hda, unless specified */
        *line_ptr,                      /* interactive input */
        line_buffer[LINE_LENGTH],
        changed[MAXIMUM_PARTS],         /* marks changed buffers */
-       buffer[SECTOR_SIZE],            /* first four partitions */
+       buffer[MAX_SECTOR_SIZE],        /* first four partitions */
        *buffers[MAXIMUM_PARTS]         /* pointers to buffers */
                = {buffer, buffer, buffer, buffer};
 
@@ -193,21 +187,22 @@ int       fd,                             /* the disk */
        ext_index,                      /* the prime extended partition */
        listing = 0,                    /* no aborts for fdisk -l */
        nowarn = 0,                     /* no warnings for fdisk -l/-s */
-       show_begin = 0,
        dos_compatible_flag = ~0,
        partitions = 4;                 /* maximum partition + 1 */
 
 uint   heads,
        sectors,
        cylinders,
+       sector_size = DEFAULT_SECTOR_SIZE,
        sector_offset = 1,
        display_factor = 1,             /* in units/sector */
        unit_flag = 1,
-       full_bits = 0,                  /* 1024 cylinders in sectors */
        extended_offset = 0,            /* offset of link pointers */
        offsets[MAXIMUM_PARTS] = {0, 0, 0, 0};
 
 int     sun_label = 0;                  /* looking at sun disklabel */
+int    sgi_label = 0;                  /* looking at sgi disklabel */
+int    aix_label = 0;                  /* looking at aix disklabel */
 
 struct partition *part_table[MAXIMUM_PARTS]    /* partitions */
                = {offset(buffer, 0), offset(buffer, 1),
@@ -231,7 +226,12 @@ struct systypes sys_types[] = {
        {0x0c, "Win95 FAT32 (LBA)"},
        {0x0e, "Win95 FAT16 (LBA)"},
        {0x0f, "Win95 Extended (LBA)"},
+       {0x11, "Hidden DOS FAT12"},
+       {0x14, "Hidden DOS FAT16"},
+       {0x16, "Hidden DOS FAT16 (big)"},
+       {0x17, "Hidden OS/2 HPFS or NTFS"},
        {0x40, "Venix 80286"},
+       {0x41, "PPC PReP Boot"},
        {0x51, "Novell?"},
        {0x52, "Microport"},            /* or CPM? */
        {0x63, "GNU HURD"},             /* or System V/386? */
@@ -256,6 +256,7 @@ struct systypes sys_types[] = {
        {0xdb, "CP/M"},                 /* or Concurrent DOS? */
        {0xe1, "DOS access"},
        {0xe3, "DOS R/O"},
+       {0xeb, "BeOS fs"},
        {0xf2, "DOS secondary"},
        {0xff, "BBT"},                  /* (bad track table) */
        { 0, NULL }
@@ -275,10 +276,21 @@ void fatal(enum failure why)
 
        switch (why) {
                case usage: message =
-"Usage: fdisk [-b] [-u] [/dev/hdx]     Change partition table\n"
-"       fdisk -l [-b] [-u] [/dev/hdx]  List partition table(s)\n"
-"       fdisk -s /dev/hdxn             Give partition size(s)\n"
-"       fdisk -v                       Give fdisk version\n";
+"Usage: fdisk [-b SSZ] [-u] [DISK]     Change partition table\n"
+"       fdisk -l [-b SSZ] [-u] [DISK]  List partition table(s)\n"
+"       fdisk -s PARTITION         Give partition size(s) in blocks\n"
+"       fdisk -v                   Give fdisk version\n"
+"Here DISK is something like /dev/hdb or /dev/sda\n"
+"and PARTITION is something like /dev/hda7\n"
+"-u: give Start and End in sector (instead of cylinder) units\n"
+"-b 2048: (for certain MO drives) use 2048-byte sectors\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);
@@ -324,6 +336,29 @@ void menu(void)
                "   w   write table to disk and exit\n"
                "   x   extra functionality (experts only)"
           );
+       else if(sgi_label)
+          puts("Command action\n"
+               "   a   select bootable partition\n"    /* sgi flavour */
+               "   b   edit bootfile entry\n"          /* sgi */
+               "   c   select sgi swap partition\n"    /* sgi flavour */
+               "   d   delete a partition\n"
+               "   l   list known partition types\n"
+               "   m   print this menu\n"
+               "   n   add a new partition\n"
+               "   o   create a new empty DOS partition table\n"
+               "   p   print the partition table\n"
+               "   q   quit without saving changes\n"
+               "   t   change a partition's system id\n"
+               "   u   change display/entry units\n"
+               "   v   verify the partition table\n"
+               "   w   write table to disk and exit\n"
+          );
+       else if(aix_label)
+          puts("Command action\n"
+               "   m   print this menu\n"
+               "   o   create a new empty DOS partition table\n"
+               "   q   quit without saving changes\n"
+          );
        else
           puts("Command action\n"
                "   a   toggle a bootable flag\n"
@@ -369,7 +404,8 @@ void xmenu(void)
                "   b   move beginning of data in a partition\n" /* !sun */
                "   c   change number of cylinders\n"
                "   d   print the raw data in the partition table\n"
-               "   e   list extended partitions\n"             /* sun */
+               "   e   list extended partitions\n"             /* !sun */
+               "   g   create an IRIX partition table\n"       /* sgi */
                "   h   change number of heads\n"
                "   m   print this menu\n"
                "   p   print the partition table\n"
@@ -381,17 +417,24 @@ void xmenu(void)
           );
 }
 
+int
+get_sysid(int i) {
+       return (
+               sun_label ? sunlabel->infos[i].id :
+               sgi_label ? sgi_get_sysid(i) : part_table[i]->sys_ind);
+}
+
+struct systypes *
+get_sys_types(void) {
+       return (
+               sun_label ? sun_sys_types :
+               sgi_label ? sgi_sys_types : sys_types);
+}
+
 char *partition_type(unsigned char type)
 {
        int i;
-       struct systypes *types;
-
-#if defined(sparc)
-       if (sun_label)
-               types = sun_sys_types;
-       else
-#endif
-               types = sys_types;
+       struct systypes *types = get_sys_types();
 
        for (i=0; types[i].name; i++)
                if (types[i].index == type)
@@ -485,34 +528,26 @@ int warn_geometry(void)
        return 1;
 }
 
-uint rounded(uint calcul, uint start)
-{
-       uint i;
-       if (!full_bits)
-               return calcul;
-       while ((i = calcul + full_bits) <= start)
-               calcul = i;
-       return calcul;
-}
-
 void update_units(void)
 {
-       full_bits = 1024 * heads * sectors;
-       if (unit_flag && full_bits)
-               display_factor = full_bits >> 10;
-       else display_factor = 1;
+       int cyl_units = heads * sectors;
+
+       if (unit_flag && cyl_units)
+               display_factor = cyl_units;
+       else
+               display_factor = 1;     /* in sectors */
 }
 
 void warn_cylinders(void)
 {
-       if (!sun_label && cylinders > 1024 && !nowarn)
-               fprintf(stderr,
-                       "The number of cylinders for this disk is set to %d.\n"
-                       "This is larger than 1024, and may cause "
-                       "problems with:\n"
-                       "1) software that runs at boot time (e.g., LILO)\n"
-                       "2) booting and partitioning software from other OSs\n"
-                       "   (e.g., DOS FDISK, OS/2 FDISK)\n",
+       if (!sun_label && !sgi_label && cylinders > 1024 && !nowarn)
+               fprintf(stderr, "\n\
+The number of cylinders for this disk is set to %d.\n\
+There is nothing wrong with that, but this is larger than 1024,\n\
+and could in certain setups cause problems with:\n\
+1) software that runs at boot time (e.g., LILO)\n\
+2) booting and partitioning software from other OSs\n\
+   (e.g., DOS FDISK, OS/2 FDISK)\n",
                        cylinders);
 }
 
@@ -537,23 +572,23 @@ void read_extended(struct partition *p)
                if (!extended_offset)
                        extended_offset = get_start_sect(p);
                if (ext2_llseek(fd, (ext2_loff_t)offsets[partitions]
-                              * SECTOR_SIZE, SEEK_SET) < 0)
+                              * sector_size, SEEK_SET) < 0)
                        fatal(unable_to_seek);
-               if (!(buffers[partitions] = (char *) malloc(SECTOR_SIZE)))
+               if (!(buffers[partitions] = (char *) malloc(sector_size)))
                        fatal(out_of_memory);
-               if (SECTOR_SIZE != read(fd, buffers[partitions], SECTOR_SIZE))
+               if (sector_size != read(fd, buffers[partitions], sector_size))
                        fatal(unable_to_read);
                part_table[partitions] = ext_pointers[partitions] = NULL;
                q = p = offset(buffers[partitions], 0);
                for (i = 0; i < 4; i++, p++) {
-                       if (IS_EXTENDED (p->sys_ind))
+                       if (IS_EXTENDED (p->sys_ind)) {
                                if (ext_pointers[partitions])
                                        fprintf(stderr, "Warning: extra link "
                                                "pointer in partition table "
                                                "%d\n", partitions + 1);
                                else
                                        ext_pointers[partitions] = p;
-                       else if (p->sys_ind)
+                       } else if (p->sys_ind) {
                                if (part_table[partitions])
                                        fprintf(stderr,
                                                "Warning: ignoring extra data "
@@ -561,15 +596,18 @@ void read_extended(struct partition *p)
                                                partitions + 1);
                                else
                                        part_table[partitions] = p;
+                       }
                }
-               if (!part_table[partitions])
+               if (!part_table[partitions]) {
                        if (q != ext_pointers[partitions])
                                part_table[partitions] = q;
                        else part_table[partitions] = q + 1;
-               if (!ext_pointers[partitions])
+               }
+               if (!ext_pointers[partitions]) {
                        if (q != part_table[partitions])
                                ext_pointers[partitions] = q;
                        else ext_pointers[partitions] = q + 1;
+               }
                p = ext_pointers[partitions++];
        }
 }
@@ -583,6 +621,9 @@ void create_doslabel(void)
        "until you decide to write them. After that, of course, the previous\n"
        "content won't be recoverable.\n\n");
 
+       sun_nolabel();  /* otherwise always recognised as sun */
+       sgi_nolabel();  /* otherwise always recognised as sgi */
+
        write_part_table_flag(buffer);
        for (i = 0; i < 4; i++)
            clear_partition(part_table[i]);
@@ -599,10 +640,11 @@ void create_doslabel(void)
  */
 int get_boot(enum action what)
 {
-       int i;
+       int i, sec_fac;
        struct hd_geometry geometry;
 
        partitions = 4;
+       sec_fac = sector_size / 512;
 
        if (what == create_empty)
                goto got_table;         /* skip reading disk */
@@ -614,11 +656,9 @@ int get_boot(enum action what)
                printf("You will not be able to write the partition table.\n");
        }
 
-#if defined(sparc)
        guess_device_type(fd);
-#endif
 
-       if (SECTOR_SIZE != read(fd, buffer, SECTOR_SIZE))
+       if (sector_size != read(fd, buffer, sector_size))
                fatal(unable_to_read);
 
 #ifdef HDIO_REQ
@@ -629,12 +669,14 @@ int get_boot(enum action what)
                heads = geometry.heads;
                sectors = geometry.sectors;
                cylinders = geometry.cylinders;
+               cylinders /= sec_fac;   /* do not round up */
                if (dos_compatible_flag)
                        sector_offset = sectors;
        } else {
                if (!ioctl(fd, BLKGETSIZE, &sectors)) {
                        heads = 1;
                        cylinders = 1;
+                       sectors /= sec_fac;
                } else {
                        heads = cylinders = sectors = 0;
                }
@@ -643,17 +685,21 @@ int get_boot(enum action what)
 
 got_table:
 
-#if defined(sparc)
        if (check_sun_label())
                return 0;
-#endif
+
+       if (check_sgi_label())
+               return 0;
+
+       if (check_aix_label())
+               return 0;
 
        if (!valid_part_table_flag(buffer)) {
                switch(what) {
                case fdisk:
                        fprintf(stderr,
                                "Device contains neither a valid DOS partition"
-                               " table, nor Sun disklabel\n");
+                               " table, nor Sun or SGI disklabel\n");
 #ifdef __sparc__
                        create_sunlabel();
 #else
@@ -676,12 +722,12 @@ got_table:
        warn_geometry();
 
        for (i = 0; i < 4; i++)
-               if(IS_EXTENDED (part_table[i]->sys_ind))
+               if(IS_EXTENDED (part_table[i]->sys_ind)) {
                        if (partitions != 4)
                                fprintf(stderr, "Ignoring extra extended "
                                        "partition %d\n", i + 1);
                        else read_extended(part_table[ext_index = i]);
-
+               }
        for (i = 3; i < partitions; i++)
                if (!valid_part_table_flag(buffers[i])) {
                        fprintf(stderr,
@@ -694,17 +740,20 @@ got_table:
        return 0;
 }
 
-int read_line(void)
+/* read line; return 0 or first char */
+int
+read_line(void)
 {
+       line_ptr = line_buffer;
        if (!fgets(line_buffer, LINE_LENGTH, stdin))
                return 0;
-       line_ptr = line_buffer;
        while (*line_ptr && !isgraph(*line_ptr))
                line_ptr++;
        return *line_ptr;
 }
 
-char read_char(char *mesg)
+char
+read_char(char *mesg)
 {
        do {
                fputs(mesg, stdout);
@@ -712,17 +761,19 @@ char read_char(char *mesg)
        return *line_ptr;
 }
 
-char read_chars(char *mesg)
+char
+read_chars(char *mesg)
 {
         fputs(mesg, stdout);
         if (!read_line()) {
                *line_ptr = '\n';
-               return '\n';
-        } else
-               return *line_ptr;
+               line_ptr[1] = 0;
+       }
+       return *line_ptr;
 }
 
-int read_hex(struct systypes *sys)
+int
+read_hex(struct systypes *sys)
 {
         int hex;
 
@@ -742,75 +793,80 @@ int read_hex(struct systypes *sys)
         }
 }
 
-
-uint read_int(uint low, uint dflt, uint high, enum offset base, char *mesg)
+/*
+ * Print the message MESG, then read an integer between LOW and HIGH.
+ * If the user hits Enter, DFLT is returned.
+ * Answers like +10 are interpreted as offsets from BASE.
+ *
+ * There is no default if DFLT is not between LOW and HIGH.
+ */
+uint
+read_int(uint low, uint dflt, uint high, uint base, char *mesg)
 {
-       uint i, use_default = 1;
-       char ms[70];
-
-       switch(base) {
-       case lower:
-           sprintf(ms, "%s ([%d]-%d): ", mesg, low, high);
-           break;
-       case upper:
-           sprintf(ms, "%s (%d-[%d]): ", mesg, low, high);
-           break;
-       case deflt:
-           sprintf(ms, "%s (%d-[%d]-%d): ", mesg, low, dflt, high);
-           break;
-       default:
-           sprintf(ms, "%s (%d-%d): ", mesg, low, high);
-           break;
+       uint i;
+       int default_ok = 1;
+       static char *ms = NULL;
+       static int mslen = 0;
+
+       if (!ms || strlen(mesg)+50 > mslen) {
+               mslen = strlen(mesg)+100;
+               if (!(ms = realloc(ms,mslen)))
+                       fatal(out_of_memory);
        }
 
+       if (dflt < low || dflt > high)
+               default_ok = 0;
+
+       if (default_ok)
+               sprintf(ms, "%s (%d-%d, default %d): ", mesg, low, high, dflt);
+       else
+               sprintf(ms, "%s (%d-%d): ", mesg, low, high);
+
        while (1) {
-               if (base == deflt) {
-                       while (read_chars(ms) != '\n' && !isdigit(*line_ptr)
-                                   && *line_ptr != '-' && *line_ptr != '+')
-                               continue;
-                       if (*line_ptr == '\n')
-                               return dflt;
-               } else {
-                       while (!isdigit(read_char(ms))
-                                   && *line_ptr != '-' && *line_ptr != '+')
-                               continue;
-               }
+               int use_default = default_ok;
+
+               /* ask question and read answer */
+               while (read_chars(ms) != '\n' && !isdigit(*line_ptr)
+                      && *line_ptr != '-' && *line_ptr != '+')
+                       continue;
+
                if (*line_ptr == '+' || *line_ptr == '-') {
-                       if (*line_ptr == '+')
-                           ++line_ptr;
-                       i = atoi(line_ptr);
-                       while (isdigit(*line_ptr))
-                       {
-                               line_ptr++;
+                       i = atoi(line_ptr+1);
+                       if (*line_ptr == '-')
+                               i = -i;
+                       while (isdigit(*++line_ptr))
                                use_default = 0;
-                       }
                        switch (*line_ptr) {
                                case 'c':
-                               case 'C': if (!unit_flag)
+                               case 'C':
+                                       if (!unit_flag)
                                                i *= heads * sectors;
                                        break;
                                case 'k':
-                               case 'K': i *= 2;
+                               case 'K':
+                                       i *= 2;
+                                       i /= (sector_size / 512);
                                        i /= display_factor;
                                        break;
                                case 'm':
-                               case 'M': i *= 2048;
+                               case 'M':
+                                       i *= 2048;
+                                       i /= (sector_size / 512);
                                        i /= display_factor;
                                        break;
-                               default: break;
-                       }
-                       switch(base) {
-                       case lower: i += low; break;
-                       case upper: i += high; break;
-                       case deflt: i += dflt; break;
-                       case ignore:
+                               case 'g':
+                               case 'G':
+                                       i *= 2048000;
+                                       i /= (sector_size / 512);
+                                       i /= display_factor;
+                                       break;
+                               default:
+                                       break;
                        }
-               }
-               else
-               {
+                       i += base;
+               } else {
                        i = atoi(line_ptr);
-                       while (isdigit(*line_ptr))
-                       {
+                       while (isdigit(*line_ptr)) {
                                line_ptr++;
                                use_default = 0;
                        }
@@ -827,19 +883,14 @@ uint read_int(uint low, uint dflt, uint high, enum offset base, char *mesg)
 
 int get_partition(int warn, int max)
 {
-       /*
-        * try to pick a default least likely to do damage,
-        * in case luser just types a newline
-        */
-       int i = read_int(1, max, max, ignore, "Partition number") - 1;
+       int i = read_int(1, 0, max, 0, "Partition number") - 1;
 
        if (warn && (
-            (!sun_label && !part_table[i]->sys_ind)
-#if defined(sparc)
+            (!sun_label && !sgi_label && !part_table[i]->sys_ind)
             || (sun_label &&
                (!sunlabel->partitions[i].num_sectors ||
                 !sunlabel->infos[i].id))
-#endif
+            || (sgi_label && (!sgi_get_num_sectors(i)))
        )) fprintf(stderr, "Warning: partition %d has empty type\n", i+1);
        return i;
 }
@@ -897,12 +948,15 @@ void delete_partition(int i)
        if (warn_geometry())
                return;
        changed[i] = 1;
-#if defined(sparc)
+
        if (sun_label) {
                sun_delete_partition(i);
                return;
        }
-#endif
+       if (sgi_label) {
+               sgi_delete_partition(i);
+               return;
+       }
        if (i < 4) {
                if (IS_EXTENDED (p->sys_ind) && i == ext_index) {
                        while (partitions > 4)
@@ -961,30 +1015,22 @@ void change_sysid(void)
        int i = get_partition(0, partitions), sys, origsys;
        struct partition *p = part_table[i];
 
-#if defined(sparc)
-       if (sun_label)
-               sys = sunlabel->infos[i].id;
-       else
-#endif
-               sys = p->sys_ind;
-       origsys = sys;
+       origsys = sys = get_sysid(i);
 
-       if (!sys)
+       if (!sys && !sgi_label)
                 printf("Partition %d does not exist yet!\n", i + 1);
         else while (1) {
-               if (!sun_label)
-                       sys = read_hex (sys_types);
-#if defined(sparc)
-               else
-                       sys = read_hex (sun_sys_types);
-#endif
-
-               if (!sys) {
-                       delete_partition(i);
-                       break;
+               sys = read_hex (get_sys_types());
+
+               if (!sys && !sgi_label) {
+                       printf("Type 0 means free space to many systems\n"
+                              "(but not to Linux). Having partitions of\n"
+                              "type 0 is probably unwise. You can delete\n"
+                              "a partition using the `d' command.\n");
+                       /* break; */
                }
 
-               if (!sun_label) {
+               if (!sun_label && !sgi_label) {
                        if (IS_EXTENDED (sys) != IS_EXTENDED (p->sys_ind)) {
                                printf("You cannot change a partition into"
                                       " an extended one or vice versa\n"
@@ -994,20 +1040,26 @@ void change_sysid(void)
                }
 
                 if (sys < 256) {
-#if defined(sparc)
                        if (sun_label && i == 2 && sys != WHOLE_DISK)
                                printf("Consider leaving partition 3 "
                                       "as Whole disk (5),\n"
                                       "as SunOS/Solaris expects it and "
-                                      "even Linux likes it.\n");
-#endif
+                                      "even Linux likes it.\n\n");
+                       if (sgi_label && ((i == 10 && sys != ENTIRE_DISK)
+                                         || (i == 8 && sys != 0)))
+                               printf("Consider leaving partition 9 "
+                                      "as volume header (0),\nand "
+                                      "partition 11 as entire volume (6)"
+                                      "as IRIX expects it.\n\n");
                         if (sys == origsys)
                             break;
-#if defined(sparc)
-                       if (sunlabel) {
+
+                       if (sun_label) {
                                sun_change_sysid(i, sys);
                        } else
-#endif
+                       if (sgi_label) {
+                               sgi_change_sysid(i, sys);
+                       } else
                                part_table[i]->sys_ind = sys;
                         printf ("Changed system type of partition %d "
                                 "to %x (%s)\n", i + 1, sys,
@@ -1096,46 +1148,65 @@ static void check_consistency(struct partition *p, int partition)
        }
 }
 
+void list_disk_geometry(void)
+{
+       printf("\nDisk %s: %d heads, %d sectors, %d cylinders\nUnits = "
+              "%ss of %d * %d bytes\n\n", disk_device, heads, sectors,
+              cylinders, str_units(), display_factor, sector_size);
+}
+
 void list_table(int xtra)
 {
        struct partition *p;
        char *type;
+       int digit_last = 0;
        int i, w;
 
-#if defined(sparc)
-       if (sun_label)
+       if (sun_label) {
                sun_list_table(xtra);
-       return;
-#endif
+               return;
+       }
+
+       if (sgi_label) {
+               sgi_list_table(xtra);
+               return;
+       }
 
        w = strlen(disk_device);
+       /* Heuristic: we list partition 3 of /dev/foo as /dev/foo3,
+          but if the device name ends in a digit, say /dev/foo1,
+          then the partition is called /dev/foo1p3. */
+       if (isdigit(disk_device[w-1]))
+               digit_last = 1;
+
+       list_disk_geometry();
 
-       printf("\nDisk %s: %d heads, %d sectors, %d cylinders\nUnits = "
-               "%ss of %d * 512 bytes\n\n", disk_device, heads, sectors,
-               cylinders, str_units(), display_factor);
        if (w < 5)
                w = 5;
-       printf("%*s Boot %s  Start      End   Blocks   Id  System\n",
-              w + 1, "Device", show_begin ? "  Begin  " : " ");
+       printf("%*s Boot    Start       End    Blocks   Id  System\n",
+              (digit_last ? w + 2 : w + 1), "Device");
 
        for (i = 0 ; i < partitions; i++) {
                if ((p = part_table[i])->sys_ind) {
                        unsigned int psects = get_nr_sects(p);
+                       unsigned int pblocks = psects;
+                       unsigned int podd = 0;
+
+                       if (sector_size < 1024) {
+                               pblocks /= (1024 / sector_size);
+                               podd = psects % (1024 / sector_size);
+                       }
+                       if (sector_size > 1024)
+                               pblocks *= (sector_size / 1024);
                         printf(
-                         show_begin
-                           ? "%*s%-2d  %c%9d%9d%9d%9d%c  %2x  %s\n"
-                           : "%*s%-2d  %c%c%9d%9d%9d%c  %2x  %s\n",
-/* device */           w, disk_device, i+1,
+                           "%*s%s%-2d  %c %9ld %9ld %9ld%c  %2x  %s\n",
+/* device */           w, disk_device, (digit_last ? "p" : ""), i+1,
 /* boot flag */                !p->boot_ind ? ' ' : p->boot_ind == ACTIVE_FLAG
                        ? '*' : '?',
-                         show_begin ?
-/* begin */            cround(rounded( calculate(p->head, p->sector, p->cyl),
-                               get_start_sect(p) + offsets[i]))
-                         : ' ',
-/* start */            cround(get_start_sect(p) + offsets[i]),
-/* end */              cround(get_start_sect(p) + offsets[i] + psects
+/* start */            (long) cround(get_start_sect(p) + offsets[i]),
+/* end */              (long) cround(get_start_sect(p) + offsets[i] + psects
                                - (psects ? 1 : 0)),
-/* odd flag on end */  psects / 2, (psects & 1) ? '+' : ' ',
+/* odd flag on end */  (long) pblocks, podd ? '+' : ' ',
 /* type id */          p->sys_ind,
 /* type name */                (type = partition_type(p->sys_ind)) ?
                        type : "Unknown");
@@ -1170,39 +1241,29 @@ void x_list_table(int extend)
                }
 }
 
-void check_bounds(uint *first, uint *last)
+void fill_bounds(uint *first, uint *last)
 {
        int i;
-       uint max = 0xffffffff;          /* used to be 256 * 63 * 1024
-                                          but that made it impossible to add a
-                                          partition crossing cylinder 8064 */
        struct partition *p = part_table[0];
 
        for (i = 0; i < partitions; p = part_table[++i]) {
                if (!p->sys_ind || IS_EXTENDED (p->sys_ind)) {
-                       first[i] = max;
+                       first[i] = 0xffffffff;
                        last[i] = 0;
                } else {
-                       first[i] = rounded(calculate(p->head, p->sector,
-                               p->cyl), get_start_sect(p) + offsets[i]);
-                       last[i] = get_start_sect(p) + offsets[i] +
-                               get_nr_sects(p) - 1;
+                       first[i] = get_start_sect(p) + offsets[i];
+                       last[i] = first[i] + get_nr_sects(p) - 1;
                }
        }
 }
 
 void check(int n, uint h, uint s, uint c, uint start)
 {
-       uint total, real_s, real_c, i;
+       uint total, real_s, real_c;
 
        real_s = sector(s) - 1;
        real_c = cylinder(s, c);
        total = (real_c * sectors + real_s) * heads + h;
-       if (full_bits)
-               while ((i = total + full_bits) <= start) {
-                       real_c += 1024;
-                       total = i;
-               }
        if (!total)
                fprintf(stderr, "Warning: partition %d contains sector 0\n", n);
        if (h >= heads)
@@ -1225,20 +1286,24 @@ void check(int n, uint h, uint s, uint c, uint start)
 void verify(void)
 {
        int i, j;
-       uint total = 1,
-               first[partitions], last[partitions];
+       uint total = 1;
+       uint first[partitions], last[partitions];
        struct partition *p = part_table[0];
 
        if (warn_geometry())
                return;
 
-#if defined(sparc)
-       if (sun_label)
+       if (sun_label) {
                verify_sun();
-       return;
-#endif
+               return;
+       }
+
+       if (sgi_label) {
+               verify_sgi(1);
+               return;
+       }
 
-       check_bounds(first, last);
+       fill_bounds(first, last);
        for (i = 0; i < partitions; p = part_table[++i])
                if (p->sys_ind && !IS_EXTENDED (p->sys_ind)) {
                        check_consistency(p, i);
@@ -1299,7 +1364,7 @@ void add_partition(int n, int sys)
                        "it before re-adding it.\n", n + 1);
                return;
        }
-       check_bounds(first, last);
+       fill_bounds(first, last);
        if (n < 4) {
                start = sector_offset;
                limit = heads * sectors * cylinders - 1;
@@ -1339,7 +1404,7 @@ void add_partition(int n, int sys)
                        uint i;
                        i = start;
                        start = read_int(cround(i), cround(i), cround(limit),
-                                        ignore, mesg);
+                                        0, mesg);
                        if (unit_flag) {
                                start = (start - 1) * display_factor;
                                if (start < i) start = i;
@@ -1370,7 +1435,7 @@ void add_partition(int n, int sys)
                sprintf(mesg, "Last %s or +size or +sizeM or +sizeK",
                        str_units());
                stop = read_int(cround(start), cround(limit), cround(limit),
-                               lower, mesg);
+                               cround(start), mesg);
                if (unit_flag) {
                        stop = stop * display_factor - 1;
                        if (stop >limit)
@@ -1384,7 +1449,7 @@ void add_partition(int n, int sys)
                ext_index = n;
                offsets[4] = extended_offset = start;
                ext_pointers[n] = p;
-               if (!(buffers[4] = calloc(1, SECTOR_SIZE)))
+               if (!(buffers[4] = calloc(1, sector_size)))
                        fatal(out_of_memory);
                part_table[4] = offset(buffers[4], 0);
                ext_pointers[4] = part_table[4] + 1;
@@ -1407,7 +1472,7 @@ void add_partition(int n, int sys)
 void add_logical(void)
 {
        if (partitions > 5 || part_table[4]->sys_ind) {
-               if (!(buffers[partitions] = calloc(1, SECTOR_SIZE)))
+               if (!(buffers[partitions] = calloc(1, sector_size)))
                        fatal(out_of_memory);
                part_table[partitions] = offset(buffers[partitions], 0);
                ext_pointers[partitions] = part_table[partitions] + 1;
@@ -1424,11 +1489,15 @@ void new_partition(void)
        if (warn_geometry())
                return;
 
-#if defined(sparc)
-       if (sun_label)
+       if (sun_label) {
                add_sun_partition(get_partition(0, partitions), LINUX_NATIVE);
-       return;
-#endif
+               return;
+       }
+
+       if (sgi_label) {
+               sgi_add_partition(get_partition(0, partitions), LINUX_NATIVE);
+               return;
+       }
 
        if (partitions >= MAXIMUM_PARTS) {
                printf("The maximum number of partitions has been created\n");
@@ -1437,13 +1506,13 @@ void new_partition(void)
 
        for (i = 0; i < 4; i++)
                free_primary += !part_table[i]->sys_ind;
-       if (!free_primary)
+       if (!free_primary) {
                if (extended_offset)
                        add_logical();
                else
                        printf("You must delete some partition and add "
                                "an extended partition first\n");
-       else {
+       else {
                char c, line[LINE_LENGTH];
                sprintf(line, "Command action\n   %s\n   p   primary "
                        "partition (1-4)\n", extended_offset ?
@@ -1475,24 +1544,25 @@ void write_table(void)
        int i, error = 0;
 
        changed[3] = changed[0] || changed[1] || changed[2] || changed[3];
-       if (!sun_label) {
+       if (!sun_label && !sgi_label) {
            for (i = 3; i < partitions; i++) {
                if (changed[i]) {
                        write_part_table_flag(buffers[i]);
                        if (ext2_llseek(fd, (ext2_loff_t)offsets[i]
-                                      * SECTOR_SIZE, SEEK_SET) < 0)
+                                      * sector_size, SEEK_SET) < 0)
                                fatal(unable_to_seek);
-                       if (write(fd, buffers[i], SECTOR_SIZE) != SECTOR_SIZE)
+                       if (write(fd, buffers[i], sector_size) != sector_size)
                                fatal(unable_to_write);
                }
            }
-       } else {
-#if defined(sparc)
+       } else if (sgi_label) {
+           /* no test on change? the printf below might be mistaken */
+           sgi_write_table();
+       } else if (sun_label) {
            if (changed[3] || changed[4] || changed[5] ||
                changed[6] || changed[7]) {
                sun_write_table();
            }
-#endif
        }
 
        printf("The partition table has been altered!\n\n");
@@ -1523,7 +1593,7 @@ void write_table(void)
                        "system to ensure the partition table is updated.\n",
                        error, strerror(error));
 
-       if (!sun_label)
+       if (!sun_label && !sgi_label)
            printf(
                "\nWARNING: If you have created or modified any DOS 6.x\n"
                "partitions, please see the fdisk manual page for additional\n"
@@ -1538,7 +1608,7 @@ void print_buffer(char buffer[])
        int     i,
                l;
 
-       for (i = 0, l = 0; i < SECTOR_SIZE; i++, l++) {
+       for (i = 0, l = 0; i < sector_size; i++, l++) {
                if (l == 0)
                        printf("0x%03X:", i);
                printf(" %02X", (unsigned char) buffer[i]);
@@ -1557,7 +1627,7 @@ void print_raw(void)
        int i;
 
        printf("Device: %s\n", disk_device);
-       if (sun_label)
+       if (sun_label || sgi_label)
                print_buffer(buffer);
        else for (i = 3; i < partitions; i++)
                print_buffer(buffers[i]);
@@ -1574,11 +1644,10 @@ void move_begin(int i)
                printf("Partition %d has no data area\n", i + 1);
                return;
        }
-       first = rounded(calculate(p->head, p->sector, p->cyl),
-                       get_start_sect(p) + offsets[i]);
+       first = get_start_sect(p) + offsets[i];
        new = read_int(first, first, 
                       get_start_sect(p) + get_nr_sects(p) + offsets[i] - 1,
-                      lower, "New beginning of data") - offsets[i];
+                      first, "New beginning of data") - offsets[i];
 
        if (new != get_nr_sects(p)) {
                first = get_nr_sects(p) + get_start_sect(p) - new;
@@ -1593,42 +1662,40 @@ void xselect(void)
        while(1) {
                putchar('\n');
                switch (tolower(read_char("Expert command (m for help): "))) {
-#if defined(sparc)
                case 'a':
                        if (sun_label)
                                sun_set_alt_cyl();
                        break;
-#endif
                case 'b':
-                       if (!sun_label)
+                       if (!sun_label && !sgi_label)
                                move_begin(get_partition(0, partitions));
                        break;
                case 'c':
                        cylinders = read_int(1, cylinders, 65535,
-                                            deflt, "Number of cylinders");
-#if defined(sparc)
+                                            0, "Number of cylinders");
                        if (sun_label)
                                sun_set_ncyl(cylinders);
-#endif
                        warn_cylinders();
                        break;
                case 'd':
                        print_raw();
                        break;
                case 'e':
-                       if (!sun_label)
-                               x_list_table(1);
-#if defined(sparc)
-                       else
+                       if (sgi_label)
+                               sgi_set_xcyl();
+                       else if (sun_label)
                                sun_set_xcyl();
-#endif
+                       else
+                               x_list_table(1);
+                       break;
+               case 'g':
+                       create_sgilabel();
                        break;
                case 'h':
-                       heads = read_int(1, heads, 256, deflt,
+                       heads = read_int(1, heads, 256, 0,
                                         "Number of heads");
                        update_units();
                        break;
-#if defined(sparc)
                case 'i':
                        if (sun_label)
                                sun_set_ilfact();
@@ -1637,13 +1704,10 @@ void xselect(void)
                        if (sun_label)
                                sun_set_rspeed();
                        break;
-#endif
                case 'p':
-#if defined(sparc)
                        if (sun_label)
                                list_table(1);
                        else
-#endif
                                x_list_table(0);
                        break;
                case 'q':
@@ -1652,7 +1716,7 @@ void xselect(void)
                case 'r':
                        return;
                case 's':
-                       sectors = read_int(1, sectors, 63, deflt,
+                       sectors = read_int(1, sectors, 63, 0,
                                           "Number of sectors");
                        if (dos_compatible_flag) {
                                sector_offset = sectors;
@@ -1668,12 +1732,10 @@ void xselect(void)
                case 'w':
                        write_table();  /* does not return */
                        break;
-#if defined(sparc)
                case 'y':
                        if (sun_label)
                                sun_set_pcylcount();
                        break;
-#endif
                default:
                        xmenu();
                }
@@ -1693,6 +1755,8 @@ is_ide_cdrom(char *device) {
     char buf[100];
     struct stat statbuf;
 
+    if (strncmp("/dev/hd", device, 7))
+       return 0;
     sprintf(buf, "/proc/ide/%s/media", device+5);
     procf = fopen(buf, "r");
     if (procf != NULL && fgets(buf, sizeof(buf), procf))
@@ -1715,10 +1779,11 @@ void try(char *device, int user_specified)
                                return;
                if ((fd = open(disk_device, type_open)) >= 0) {
                        if (get_boot(try_only) < 0) {
+                               list_disk_geometry();
                                if (btrydev(device) < 0)
                                        fprintf(stderr,
-                                               "Disk doesn't contain a valid "
-                                               "partition table\n");
+                                               "Disk %s doesn't contain a valid "
+                                               "partition table\n", device);
                                close(fd);
                        } else {
                                close(fd);
@@ -1741,7 +1806,8 @@ void try(char *device, int user_specified)
 void
 dummy(int *kk) {}
 
-void main(int argc, char **argv)
+int
+main(int argc, char **argv)
 {
        int i, j, s, c;
        int optl = 0, opts = 0;
@@ -1751,14 +1817,18 @@ void main(int argc, char **argv)
        /*
         * Calls:
         *  fdisk -v
-        *  fdisk -l [-b] [-u] [device] ...
+        *  fdisk -l [-b sectorsize] [-u] [device] ...
         *  fdisk -s [partition] ...
-        *  fdisk [-b] [-u] [device]
+        *  fdisk [-b sectorsize] [-u] [device]
         */
-       while ((c = getopt(argc, argv, "blsuv")) != EOF) {
+       while ((c = getopt(argc, argv, "b:lsuv")) != EOF) {
                switch (c) {
                case 'b':
-                       show_begin = 1;
+                       sector_size = atoi(optarg);
+                       if (sector_size != 512 && sector_size != 1024 &&
+                           sector_size != 2048)
+                               fatal(usage);
+                       sector_offset = 2;
                        break;
                case 'l':
                        optl = 1;
@@ -1770,7 +1840,7 @@ void main(int argc, char **argv)
                        unit_flag = 0;
                        break;
                case 'v':
-                       printf("fdisk v" VERSION "\n");
+                       printf("fdisk v" UTIL_LINUX_VERSION "\n");
                        exit(0);
                default:
                        fatal(usage);
@@ -1801,18 +1871,27 @@ void main(int argc, char **argv)
                        try("/dev/sdf", 0);
                        try("/dev/sdg", 0);
                        try("/dev/sdh", 0);
-                       try("/dev/eda", 0);
+                       try("/dev/eda", 0); /* PS/2 ESDI drives */
                        try("/dev/edb", 0);
                        try("/dev/edc", 0);
                        try("/dev/edd", 0);
+                       try("/dev/rd/c0d0", 0); /* DAC960 RAID disks */
+                       try("/dev/rd/c0d1", 0);
+                       try("/dev/rd/c0d2", 0);
+                       try("/dev/rd/c0d3", 0);
+                       try("/dev/rd/c0d4", 0);
+                       try("/dev/rd/c0d5", 0);
+                       try("/dev/rd/c0d6", 0);
+                       try("/dev/rd/c0d7", 0);
                }
                exit(0);
        }
 
        if (opts) {
-               /* Silly assumptions here about device naming */
+               /* Very silly assumptions here about device naming */
+               /* All this junk will disappear again */
                nowarn = 1;
-               disk_device = (char *) malloc(9);
+               disk_device = (char *) malloc(16);
                type_open = O_RDONLY;
 
                opts = argc - optind;
@@ -1821,13 +1900,24 @@ void main(int argc, char **argv)
 
                for (j = optind; j < argc; j++) {
                        part = argv[j];
-                       if (strlen(part) < 9)
-                               fatal(usage);
-                       if (!(i = atoi(part + 8)))
-                               fatal(usage);
-                       i--;    /* count from 0 */
-                       strncpy(disk_device, part, 8);
-                       disk_device[8] = 0;
+                        if (strncmp(part, "/dev/rd/", 8) == 0) {
+                                char *p = strrchr(part, 'p');
+                                if (p == NULL)
+                                        fatal(usage);
+                                if (!(i = atoi(p + 1)))
+                                        fatal(usage);
+                               i--;    /* count from 0 */
+                                *p = '\0';
+                                strcpy(disk_device, part);
+                        } else {
+                               if (strlen(part) < 9)
+                                       fatal(usage);
+                               if (!(i = atoi(part + 8)))
+                                       fatal(usage);
+                               i--;    /* count from 0 */
+                               strncpy(disk_device, part, 8);
+                               disk_device[8] = 0;
+                       }
                        if ((fd = open(disk_device, type_open)) < 0)
                                fatal(unable_to_open);
                        close(fd);
@@ -1869,37 +1959,50 @@ void main(int argc, char **argv)
                putchar('\n');
                switch (tolower(read_char("Command (m for help): "))) {
                case 'a':
-#if defined(sparc)
                        if (sun_label)
                                toggle_sunflags(get_partition(1, partitions),
                                                0x01);
                        else
-#endif
-                               toggle_active(get_partition(1, partitions));
+                               if (sgi_label)
+                                       sgi_set_bootpartition(
+                                               get_partition(1, partitions));
+                               else
+                                       toggle_active(get_partition(1, partitions));
                        break;
                case 'b':
-                       bselect();
+                       if (sgi_label) {
+                               printf("\nThe current boot file is: %s\n",
+                                      sgi_get_bootfile());
+                               if (read_chars("Please enter the name of the "
+                                              "new boot file: ") == '\n')
+                                       printf("Boot file unchanged\n");
+                               else
+                                       sgi_set_bootfile(line_ptr);
+                       } else
+                               bselect();
                        break;
                case 'c':
-#if defined(sparc)
                        if (sun_label)
                                toggle_sunflags(get_partition(1, partitions),
                                                0x10);
                        else
-#endif
-                               toggle_dos();
+                               if (sgi_label)
+                                       sgi_set_swappartition(
+                                               get_partition(1, partitions));
+                               else
+                                       toggle_dos();
                        break;
                case 'd':
                        delete_partition(
                                get_partition(1, partitions));
                        break;
-               case 'l':
-#if defined(sparc)
-                       if (sun_label)
-                               list_types(sun_sys_types);
+               case 'i':
+                       if (sgi_label)
+                               create_sgiinfo();
                        else
-#endif
-                               list_types(sys_types);
+                               menu();
+               case 'l':
+                       list_types(get_sys_types());
                        break;
                case 'n':
                        new_partition();
@@ -1913,11 +2016,9 @@ void main(int argc, char **argv)
                case 'q':
                        close(fd);
                        exit(0);
-#if defined(sparc)
                case 's':
                        create_sunlabel();
                        break;
-#endif
                case 't':
                        change_sysid();
                        break;
@@ -1931,10 +2032,15 @@ void main(int argc, char **argv)
                        write_table();          /* does not return */
                        break;
                case 'x':
-                       xselect();
+                       if( sgi_label ) {
+                               fprintf(stderr,
+                                       "\n\tSorry, no experts menu for SGI "
+                                       "partition tables available.\n\n");
+                       } else
+                               xselect();
                        break;
                default: menu();
                }
        }
+       return 0;
 }
-
similarity index 73%
rename from disk-utils/fdisk.h
rename to fdisk/fdisk.h
index 11f529d48ae0c10bc67587922c9ef1f1b279427f..080515e5ff967a6b6f5f534e59faba02705972ba 100644 (file)
@@ -2,9 +2,23 @@
    fdisk.h
 */
 
-#define SECTOR_SIZE    512
+#define DEFAULT_SECTOR_SIZE    512
+#define MAX_SECTOR_SIZE        2048
+#define SECTOR_SIZE    512     /* still used in BSD code */
 #define MAXIMUM_PARTS  60
 
+#define ACTIVE_FLAG     0x80
+
+#define EXTENDED        0x05
+#define WIN98_EXTENDED  0x0f
+#define LINUX_PARTITION 0x81
+#define LINUX_SWAP      0x82
+#define LINUX_NATIVE    0x83
+#define LINUX_EXTENDED  0x85
+
+#define IS_EXTENDED(i) \
+       ((i) == EXTENDED || (i) == WIN98_EXTENDED || (i) == LINUX_EXTENDED)
+
 #define SIZE(a)        (sizeof(a)/sizeof((a)[0]))
 
 #define cround(n)      (((n) + display_factor * unit_flag) / display_factor)
@@ -33,9 +47,7 @@ struct partition {
 };
 
 enum failure {usage, unable_to_open, unable_to_read, unable_to_seek,
-       unable_to_write, out_of_memory};
-
-enum offset {ignore, lower, deflt, upper};
+       unable_to_write, out_of_memory, no_partition, no_device};
 
 enum action {fdisk, require, try_only, create_empty};
 
@@ -59,14 +71,15 @@ 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);
-uint read_int(uint low, uint dflt, uint high, enum offset base, char *mesg);
+uint read_int(uint low, uint dflt, uint high, uint base, char *mesg);
 extern char *const str_units(void);
 
 extern unsigned int get_start_sect(struct partition *p);
 extern unsigned int get_nr_sects(struct partition *p);
 
-/* prototypes for fdisklabel.c */
+/* prototypes for fdiskbsdlabel.c */
 extern void bselect(void);
 extern int btrydev (char * dev);
 
-/* prototypes for fdisksunlabel.c */
+/* prototypes for fdisksgilabel.c */
+extern int valid_part_table_flag(unsigned char *b);
diff --git a/fdisk/fdiskaixlabel.c b/fdisk/fdiskaixlabel.c
new file mode 100644 (file)
index 0000000..848a6ec
--- /dev/null
@@ -0,0 +1,64 @@
+#include <stdio.h>              /* stderr */
+#include <stdlib.h>             /* uint */
+#include <string.h>             /* strstr */
+#include <unistd.h>             /* write */
+
+#include <endian.h>
+
+#include "fdisk.h"
+#include "fdiskaixlabel.h"
+
+static int     other_endian = 0;
+static  short  volumes=1;
+
+/*
+ * only dealing with free blocks here
+ */
+
+void
+aix_info( void )
+{
+    printf(
+       "\n\tThere is a valid AIX label on this disk.\n"
+       "\tUnfortunately Linux cannot handle these\n"
+       "\tdisks at the moment.  Nevertheless some\n"
+       "\tadvice:\n"
+       "\t1. fdisk will destroy its contents on write.\n"
+       "\t2. Be sure that this disk is NOT a still vital\n"
+       "\t   part of a volume group. (Otherwise you may\n"
+       "\t   erase the other disks as well, if unmirrored.)\n"
+       "\t3. Before deleting this physical volume be sure\n"
+       "\t   to remove the disk logically from your AIX\n"
+       "\t   machine.  (Otherwise you become an AIXpert).\n"
+    );
+}
+
+void
+aix_nolabel( void )
+{
+    aixlabel->magic = 0;
+    aix_label = 0;
+    partitions = 4;
+    memset( buffer, 0, sizeof(buffer) );       /* avoid fdisk cores */
+    return;
+}
+
+int
+check_aix_label( void )
+{
+    if (aixlabel->magic != AIX_LABEL_MAGIC &&
+       aixlabel->magic != AIX_LABEL_MAGIC_SWAPPED) {
+       aix_label = 0;
+       other_endian = 0;
+       return 0;
+    }
+    other_endian = (aixlabel->magic == AIX_LABEL_MAGIC_SWAPPED);
+    update_units();
+    aix_label = 1;
+    partitions= 1016;
+    volumes = 15;
+    aix_info();
+    aix_nolabel();             /* %% */
+    aix_label = 1;             /* %% */
+    return 1;
+}
diff --git a/fdisk/fdiskaixlabel.h b/fdisk/fdiskaixlabel.h
new file mode 100644 (file)
index 0000000..fd95bc0
--- /dev/null
@@ -0,0 +1,34 @@
+#include <linux/types.h>   /* for __u32 etc */
+/*
+ * Copyright (C) Andreas Neuper, Sep 1998.
+ *     This file may be redistributed under
+ *     the terms of the GNU Public License.
+ */
+
+typedef struct {
+       unsigned int   magic;        /* expect AIX_LABEL_MAGIC */
+       unsigned int   fillbytes1[124];
+       unsigned int   physical_volume_id;
+       unsigned int   fillbytes2[124];
+} aix_partition;
+
+#define        AIX_LABEL_MAGIC         0xc9c2d4c1
+#define        AIX_LABEL_MAGIC_SWAPPED 0xc1d4c2c9
+#define        AIX_INFO_MAGIC          0x00072959
+#define        AIX_INFO_MAGIC_SWAPPED  0x59290700
+
+/* fdisk.c */
+#define aixlabel ((aix_partition *)buffer)
+extern char buffer[MAX_SECTOR_SIZE];
+extern char changed[MAXIMUM_PARTS];
+extern uint heads, sectors, cylinders;
+extern int show_begin;
+extern int aix_label;
+extern char *partition_type(unsigned char type);
+extern void update_units(void);
+extern char read_chars(char *mesg);
+
+/* fdiskaixlabel.c */
+extern struct  systypes aix_sys_types[];
+extern void    aix_nolabel( void );
+extern int     check_aix_label( void );
similarity index 96%
rename from disk-utils/fdisklabel.c
rename to fdisk/fdiskbsdlabel.c
index d98d49d0dbe688db4a5c653ef811ad701eb87af0..8edec23314bd46114ad5fe41216c12900b96a443 100644 (file)
@@ -52,7 +52,7 @@
 #include "fdisk.h"
 #define NETBSD_PARTITION 0xa5
 #define DKTYPENAMES
-#include "fdisklabel.h"
+#include "fdiskbsdlabel.h"
 
 static void xbsd_delete_part (void);
 static void xbsd_new_part (void);
@@ -118,20 +118,27 @@ bmenu (void)
        );
 }
 
+int
+hidden(int type) {
+       return type ^ 0x10;
+}
+
+int
+is_netbsd_partition_type(int type) {
+       return (type == NETBSD_PARTITION || type == hidden(NETBSD_PARTITION));
+}
+
 void
-bselect (void)
-{
+bselect (void) {
 #if defined (i386) || defined (sparc)
   int t, ss;
 
   for (t=0; t<4; t++)
-    if (part_table[t] -> sys_ind == NETBSD_PARTITION)
-    {
+    if (is_netbsd_partition_type(part_table[t] -> sys_ind)) {
       xbsd_part = part_table[t];
       xbsd_part_index = t;
       ss = get_start_sect(xbsd_part);
-      if (ss == 0)
-      {
+      if (ss == 0) {
         fprintf (stderr, "Partition %s%d has invalid starting sector 0.\n",
                 disk_device, t+1);
         return;
@@ -144,9 +151,8 @@ bselect (void)
       break;
     }
 
-  if (t == 4)
-  {
-    printf ("There is no NetBSD partition on %s.\n", disk_device);
+  if (t == 4) {
+    printf ("There is no *BSD partition on %s.\n", disk_device);
     return;
   }
 
@@ -234,16 +240,18 @@ xbsd_new_part (void)
 #if defined (i386) || defined (sparc)
   begin = get_start_sect(xbsd_part);
   end = begin + get_nr_sects(xbsd_part) - 1;
-#elif defined (__alpha__)
+#elif defined (__alpha__) || defined (__powerpc__)
   begin = 0;
   end = xbsd_dlabel.d_secperunit;
 #endif
 
   sprintf (mesg, "First %s", str_units());
-  begin = read_int (cround (begin), cround (begin), cround (end), ignore, mesg);
+  begin = read_int (cround (begin), cround (begin), cround (end),
+                   0, mesg);
 
   sprintf (mesg, "Last %s or +size or +sizeM or +sizeK", str_units());
-  end = read_int (cround (begin), cround (end), cround (end), ignore, mesg);
+  end = read_int (cround (begin), cround (end), cround (end),
+                 cround (begin), mesg);
 
   if (unit_flag)
   {
@@ -388,7 +396,7 @@ xbsd_create_disklabel (void)
     {
 #if defined (i386) || defined (sparc)
       if (xbsd_initlabel (xbsd_part, &xbsd_dlabel, xbsd_part_index) == 1)
-#elif defined (__alpha__)
+#elif defined (__alpha__) || defined (__powerpc__)
       if (xbsd_initlabel (NULL, &xbsd_dlabel, 0) == 1)
 #endif
       {
@@ -519,6 +527,8 @@ xbsd_write_bootstrap (void)
 
 #if defined (i386) || defined (sparc)
   sector = get_start_sect(xbsd_part);
+#elif defined (__powerpc__)
+  sector = 0;
 #elif defined (__alpha__)
   sector = 0;
   alpha_bootblock_checksum (buffer);
@@ -718,7 +728,7 @@ xbsd_writelabel (struct partition *p, struct xbsd_disklabel *d)
 
 #if defined (i386) || defined (sparc)
   sector = get_start_sect(p) + BSD_LABELSECTOR;
-#elif defined (__alpha__)
+#elif defined (__alpha__) || defined (__powerpc__)
   sector = BSD_LABELSECTOR;
 #endif
 
similarity index 99%
rename from disk-utils/fdisklabel.h
rename to fdisk/fdiskbsdlabel.h
index 06435f4d1dc152adf113c150e35a914c1f25da90..b9f2c9c3851d7ca62da446ae5a4fbbf7b1f046c0 100644 (file)
@@ -46,7 +46,7 @@
 #if defined (i386) || defined (sparc)
 #define BSD_LABELSECTOR   1
 #define BSD_LABELOFFSET   0
-#elif defined (__alpha__)
+#elif defined (__alpha__) || defined (__powerpc__)
 #define BSD_LABELSECTOR   0
 #define BSD_LABELOFFSET   64
 #else
diff --git a/fdisk/fdisksgilabel.c b/fdisk/fdisksgilabel.c
new file mode 100644 (file)
index 0000000..42f7363
--- /dev/null
@@ -0,0 +1,888 @@
+/*
+ *
+ * fdisksgilabel.c
+ *
+ * Copyright (C) Andreas Neuper, Sep 1998.
+ *     This file may be modified and redistributed under
+ *     the terms of the GNU Public License.
+ */
+#include <stdio.h>              /* stderr */
+#include <stdlib.h>             /* uint */
+#include <string.h>             /* strstr */
+#include <unistd.h>             /* write */
+#include <sys/ioctl.h>          /* ioctl */
+#include <sys/stat.h>           /* stat */
+#include <assert.h>             /* assert */
+
+#include <endian.h>
+#include <linux/major.h>        /* FLOPPY_MAJOR */
+#include <linux/hdreg.h>        /* HDIO_GETGEO */
+
+#include "fdisk.h"
+#include "fdisksgilabel.h"
+
+static int     other_endian = 0;
+static int     debug = 0;
+static  short volumes=1;
+
+/*
+ * only dealing with free blocks here
+ */
+
+typedef struct { int first; int last; } freeblocks;
+static freeblocks freelist[17]; /* 16 partitions can produce 17 vacant slots */
+void setfreelist( int i, int f, int l ) \
+       { freelist[i].first = f; freelist[i].last = l; return; }
+void add2freelist( int f, int l ) \
+       { int i = 0; for( ; i<17 ; i++ ) { if(freelist[i].last==0) break; }\
+         setfreelist( i, f, l ); return; }
+void clearfreelist( void )             \
+       { int i = 0; for( ; i<17 ; i++ ) { setfreelist( i, 0, 0 ); } return; }
+int  isinfreelist( int b )             \
+       { int i = 0; for( ; i<17 ; i++ )\
+       { if( ( freelist[i].first <= b ) && ( freelist[i].last >= b) )\
+       { return freelist[i].last; } } return 0; }
+       /* return last vacant block of this stride (never 0). */
+       /* the '>=' is not quite correct, but simplifies the code */
+/*
+ * end of free blocks section
+ */
+
+struct systypes sgi_sys_types[] = {
+    {SGI_VOLHDR,  "SGI volhdr"},
+    {0x01,       "SGI trkrepl"},
+    {0x02,       "SGI secrepl"},
+    {SGI_SWAP,   "SGI raw"},
+    {0x04,       "SGI bsd"},
+    {0x05,       "SGI sysv"},
+    {ENTIRE_DISK, "SGI volume"},
+    {SGI_EFS,    "SGI efs"},
+    {0x08,       "SGI lvol"},
+    {0x09,       "SGI rlvol"},
+    {0x0A,       "SGI xfs"},
+    {0x0B,       "SGI xlvol"},
+    {0x0C,       "SGI rxlvol"},
+    {LINUX_SWAP,  "Linux swap"},
+    {LINUX_NATIVE,"Linux native"},
+    {0, NULL }
+};
+
+static inline unsigned short __swap16(unsigned short x) {
+        return (((__u16)(x) & 0xFF) << 8) | (((__u16)(x) & 0xFF00) >> 8);
+}
+static inline __u32 __swap32(__u32 x) {
+        return (((__u32)(x) & 0xFF) << 24) | (((__u32)(x) & 0xFF00) << 8) | (((__u32)(x) & 0xFF0000) >> 8) | (((__u32)(x) & 0xFF000000) >> 24);
+}
+
+static
+int
+sgi_get_nsect( void )
+{
+    return SSWAP16(sgilabel->devparam.nsect);
+}
+
+static
+int
+sgi_get_ntrks( void )
+{
+    return SSWAP16(sgilabel->devparam.ntrks);
+}
+
+#if 0
+static int
+sgi_get_head_vol0( void )
+{
+    return SSWAP16(sgilabel->devparam.head_vol0);
+}
+
+static int
+sgi_get_bytes( void )
+{
+    return SSWAP16(sgilabel->devparam.bytes);
+}
+#endif
+
+static
+int
+sgi_get_pcylcount( void )
+{
+    return SSWAP16(sgilabel->devparam.pcylcount);
+}
+
+void
+sgi_nolabel()
+{
+    sgilabel->magic = 0;
+    sgi_label = 0;
+    partitions = 4;
+}
+
+unsigned int
+two_s_complement_32bit_sum(
+    unsigned int* base,
+    int size /* in bytes */ )
+{
+    int i=0;
+    unsigned int sum=0;
+    size = size / sizeof( unsigned int );
+    for( i=0; i<size; i++ )
+    {
+       sum = sum - SSWAP32(base[i]);
+    }
+    return sum;
+}
+
+int check_sgi_label()
+{
+    if (sizeof(sgilabel) > 512) {
+           fprintf(stderr,
+                   "According to MIPS Computer Systems, Inc the "
+                   "Label must not contain more than 512 bytes\n");
+           exit(1);
+    }
+
+    if (sgilabel->magic != SGI_LABEL_MAGIC &&
+       sgilabel->magic != SGI_LABEL_MAGIC_SWAPPED) {
+       sgi_label = 0;
+       other_endian = 0;
+       return 0;
+    }
+
+    other_endian = (sgilabel->magic == SGI_LABEL_MAGIC_SWAPPED);
+    /*
+     * test for correct checksum
+     */
+    if( two_s_complement_32bit_sum( (unsigned int*)sgilabel,
+                       sizeof(*sgilabel) ) )
+    {
+       fprintf( stderr, "Detected sgi disklabel with wrong checksum.\n" );
+    } else
+    {
+       heads = sgi_get_ntrks();
+       cylinders = sgi_get_pcylcount();
+       sectors = sgi_get_nsect();
+    }
+    update_units();
+    sgi_label = 1;
+    partitions= 16;
+    volumes = 15;
+    return 1;
+}
+
+void
+sgi_list_table( int xtra )
+{
+    int i, w;
+    char *type;
+
+    w = strlen( disk_device );
+
+    if( xtra )
+    {
+       printf( "\nDisk %s (SGI disk label): %d heads, %d sectors\n"
+              "%d cylinders, %d physical cylinders\n"
+              "%d extra sects/cyl, interleave %d:1\n"
+              "%s\n"
+              "Units = %ss of %d * 512 bytes\n\n",
+              disk_device, heads, sectors, cylinders,
+              SSWAP16(sgiparam.pcylcount),
+              SSWAP16(sgiparam.sparecyl),
+              SSWAP16(sgiparam.ilfact),
+              (char *)sgilabel,
+              str_units(), display_factor);
+    } else
+    {
+       printf( "\nDisk %s (SGI disk label): %d heads, %d sectors, %d cylinders\n"
+               "Units = %ss of %d * 512 bytes\n\n",
+               disk_device, heads, sectors, cylinders,
+               str_units(), display_factor );
+    }
+    printf("----- partitions -----\n"
+          "%*s  Info      Start       End   Sectors  Id  System\n",
+          w + 1, "Device");
+    for (i = 0 ; i < partitions; i++)
+    {
+       if( sgi_get_num_sectors(i) || debug )
+       {
+           __u32 start = sgi_get_start_sector(i);
+           __u32 len = sgi_get_num_sectors(i);
+           printf(
+               "%*s%-2d %4s %9ld %9ld %9ld  %2x  %s\n",
+/* device */              w, disk_device, i + 1,
+/* flags */               (sgi_get_swappartition() == i) ? "swap" :
+/* flags */               (sgi_get_bootpartition() == i) ? "boot" : "    ", 
+/* start */               (long) scround(start),
+/* end */                 (long) scround(start+len)-1,
+/* no odd flag on end */  (long) len, 
+/* type id */             sgi_get_sysid(i),
+/* type name */           (type = partition_type(sgi_get_sysid(i)))
+                   ? type : "Unknown");
+       }
+    }
+    printf(    "----- bootinfo -----\nBootfile: %s\n"
+               "----- directory entries -----\n",
+               sgilabel->boot_file );
+    for (i = 0 ; i < volumes; i++)
+    {
+       if (sgilabel->directory[i].vol_file_size)
+       {
+           __u32 start = SSWAP32(sgilabel->directory[i].vol_file_start);
+           __u32 len = SSWAP32(sgilabel->directory[i].vol_file_size);
+           char*name = sgilabel->directory[i].vol_file_name;
+           printf("%2d: %-10s sector%5u size%8u\n",
+                   i, name, (unsigned int) start, (unsigned int) len);
+       }
+    }
+}
+
+int
+sgi_get_start_sector( int i )
+{
+    return SSWAP32(sgilabel->partitions[i].start_sector);
+}
+
+int
+sgi_get_num_sectors( int i )
+{
+    return SSWAP32(sgilabel->partitions[i].num_sectors);
+}
+
+int
+sgi_get_sysid( int i )
+{
+    return SSWAP32(sgilabel->partitions[i].id);
+}
+
+int
+sgi_get_bootpartition( void )
+{
+    return SSWAP16(sgilabel->boot_part);
+}
+
+int
+sgi_get_swappartition( void )
+{
+    return SSWAP16(sgilabel->swap_part);
+}
+
+void
+sgi_set_bootpartition( int i )
+{
+    sgilabel->boot_part = SSWAP16(((short)i));
+    return;
+}
+
+int
+sgi_get_lastblock( void )
+{
+    return heads * sectors * cylinders;
+}
+
+void
+sgi_set_swappartition( int i )
+{
+    sgilabel->swap_part = SSWAP16(((short)i));
+    return;
+}
+
+static int
+sgi_check_bootfile( const char* aFile )
+{
+    if( strlen( aFile ) < 3 ) /* "/a\n" is minimum */
+    {
+       printf( "\nInvalid Bootfile!\n"
+               "\tThe bootfile must be an absolute non-zero pathname,\n"
+               "\te.g. \"/unix\" or \"/unix.save\".\n" );
+       return 0;
+    } else
+    if( strlen( aFile ) > 16 )
+    {
+       printf( "\n\tName of Bootfile too long:  16 bytes maximum.\n" );
+       return 0;
+    } else
+    if( aFile[0] != '/' )
+    {
+       printf( "\n\tBootfile must have a fully qualified pathname.\n" );
+       return 0;
+    }
+    if( strncmp( aFile, sgilabel->boot_file, 16 ) )
+    {
+       printf( "\n\tBe aware, that the bootfile is not checked for existence.\n\t"
+               "SGI's default is \"/unix\" and for backup \"/unix.save\".\n" );
+       /* filename is correct and did change */
+       return 1;
+    }
+    return 0;  /* filename did not change */
+}
+
+const char *
+sgi_get_bootfile(void) {
+       return sgilabel->boot_file;
+}
+
+void
+sgi_set_bootfile( const char* aFile )
+{
+    int i = 0;
+    if( sgi_check_bootfile( aFile ) )
+    {
+       while( i<16 )
+       {
+           if( (aFile[i] != '\n')      /* in principle caught again by next line */
+           &&  (strlen( aFile ) > i ) )
+               sgilabel->boot_file[i] = aFile[i];
+           else
+               sgilabel->boot_file[i] = 0;
+           i++;
+       }
+       printf( "\n\tBootfile is changed to \"%s\".\n", sgilabel->boot_file );
+    }
+    return;
+}
+
+void
+create_sgiinfo( void )
+{
+    /* I keep SGI's habit to write the sgilabel to the second block */
+    sgilabel->directory[0].vol_file_start = SSWAP32( 2 );
+    sgilabel->directory[0].vol_file_size = SSWAP32( sizeof( sgiinfo ) );
+    strncpy( sgilabel->directory[0].vol_file_name, "sgilabel",8 );
+    return;
+}
+
+sgiinfo * fill_sgiinfo( void );
+
+void
+sgi_write_table( void )
+{
+    sgilabel->csum = 0;
+    sgilabel->csum = SSWAP32( two_s_complement_32bit_sum(
+                                (unsigned int*)sgilabel, 
+                                sizeof(*sgilabel) ) );
+    assert( two_s_complement_32bit_sum(
+           (unsigned int*)sgilabel, sizeof(*sgilabel) ) == 0 );
+    if( lseek(fd, 0, SEEK_SET) < 0 )
+       fatal(unable_to_seek);
+    if( write(fd, sgilabel, SECTOR_SIZE) != SECTOR_SIZE )
+       fatal(unable_to_write);
+    if( ! strncmp( sgilabel->directory[0].vol_file_name, "sgilabel",8 ) )
+    {
+       /*
+        * keep this habbit of first writing the "sgilabel".
+        * I never tested whether it works without (AN 981002).
+        */
+       sgiinfo*info = fill_sgiinfo();  /* fills the block appropriately */
+       int infostartblock = SSWAP32( sgilabel->directory[0].vol_file_start );
+       if( ext2_llseek(fd, (ext2_loff_t)infostartblock*
+           SECTOR_SIZE, SEEK_SET) < 0 )
+           fatal(unable_to_seek);
+       if( write(fd, info, SECTOR_SIZE) != SECTOR_SIZE )
+           fatal(unable_to_write);
+       free( info );
+    }
+    return;
+}
+
+static
+int
+compare_start( int*x, int*y )
+{
+    /*
+     * sort according to start sectors
+     * and prefers largest partition:
+     * entry zero is entire disk entry
+     */
+    int i = *x;
+    int j = *y;
+    int a = sgi_get_start_sector(i);
+    int b = sgi_get_start_sector(j);
+    int c = sgi_get_num_sectors(i);
+    int d = sgi_get_num_sectors(j);
+    if( a == b )
+    {
+       return( d - c );
+    }
+    return( a - b );
+}
+
+static
+int
+sgi_gaps()
+{
+    /*
+     * returned value is:
+     *  = 0 : disk is properly filled to the rim
+     *  < 0 : there is an overlap
+     *  > 0 : there is still some vacant space
+     */
+    return verify_sgi(0);
+}
+
+int
+verify_sgi( int verbose )
+{
+    int Index[16];     /* list of valid partitions */
+    int sortcount = 0; /* number of used partitions, i.e. non-zero lengths */
+    int compare_start();/* comparison function above */
+    int entire = 0, i = 0;     /* local counters */
+    int start = 0;
+    int gap = 0;       /* count unused blocks */
+    int lastblock = sgi_get_lastblock();
+    /*
+     */
+    clearfreelist();
+    for( i=0; i<16; i++ )
+    {
+       if( sgi_get_num_sectors(i)!=0 )
+       {
+           Index[sortcount++]=i;
+           if( sgi_get_sysid(i) == ENTIRE_DISK )
+           {
+               if( entire++ == 1 )
+               {
+                   if(verbose)
+                       printf("More than one entire disk entriy present.\n");
+               }
+           }
+       }
+    }
+    if( sortcount == 0 )
+    {
+       if(verbose)
+           printf("No partitions defined\n");
+        return lastblock;
+    }
+    qsort( Index, sortcount, sizeof(Index[0]), (void*)compare_start );
+    if( sgi_get_sysid( Index[0] ) == ENTIRE_DISK )
+    {
+       if( ( Index[0] != 10 ) && verbose )
+           printf( "IRIX likes when Partition 11 covers the entire disk.\n" );
+       if( ( sgi_get_start_sector( Index[0] ) != 0 ) && verbose )
+           printf( "The entire disk partition should start at block 0,\nnot "
+                   "at diskblock %d.\n", sgi_get_start_sector(Index[0] ) );
+    if(debug)  /* I do not understand how some disks fulfil it */
+       if( ( sgi_get_num_sectors( Index[0] ) != lastblock ) && verbose )
+           printf( "The entire disk partition is only %d diskblock large,\n"
+                   "but the disk is %d diskblocks long.\n",
+                   sgi_get_num_sectors( Index[0] ), lastblock );
+       lastblock = sgi_get_num_sectors( Index[0] );
+    } else
+    {
+       if( verbose )
+           printf( "One Partition (#11) should cover the entire disk.\n" );
+       if(debug>2)
+           printf( "sysid=%d\tpartition=%d\n",
+                       sgi_get_sysid( Index[0] ), Index[0]+1 );
+    }
+    for( i=1, start=0; i<sortcount; i++ )
+    {
+       int cylsize = sgi_get_nsect() * sgi_get_ntrks();
+       if( (sgi_get_start_sector( Index[i] ) % cylsize) != 0 )
+       {
+       if(debug)       /* I do not understand how some disks fulfil it */
+           if( verbose )
+               printf( "Partition %d does not start on cylinder boundary.\n",
+                       Index[i]+1 );
+       }
+       if( sgi_get_num_sectors( Index[i] ) % cylsize != 0 )
+       {
+       if(debug)       /* I do not understand how some disks fulfil it */
+           if( verbose )
+               printf( "Partition %d does not end on cylinder boundary.\n",
+                       Index[i]+1 );
+       }
+       /* We cannot handle several "entire disk" entries. */
+       if( sgi_get_sysid( Index[i] ) == ENTIRE_DISK ) continue;
+       if( start > sgi_get_start_sector( Index[i] ) )
+       {
+           if( verbose )
+               printf( "The Partition %d and %d overlap by %d sectors.\n",
+                       Index[i-1]+1, Index[i]+1,
+                       start - sgi_get_start_sector( Index[i] ) );
+           if( gap >  0 ) gap = -gap;
+           if( gap == 0 ) gap = -1;
+       }
+       if( start < sgi_get_start_sector( Index[i] ) )
+       {
+           if( verbose )
+               printf( "Unused gap of %8d sectors - sectors %8d-%d\n",
+                       sgi_get_start_sector( Index[i] ) - start,
+                       start, sgi_get_start_sector( Index[i] )-1 );
+           gap += sgi_get_start_sector( Index[i] ) - start;
+           add2freelist( start, sgi_get_start_sector( Index[i] ) );
+       }
+       start = sgi_get_start_sector( Index[i] )
+             + sgi_get_num_sectors(  Index[i] );
+       if(debug>1)
+       {
+           if( verbose )
+               printf( "%2d:%12d\t%12d\t%12d\n", Index[i],
+                       sgi_get_start_sector(Index[i]),
+                       sgi_get_num_sectors(Index[i]),
+                       sgi_get_sysid(Index[i]) );
+       }
+    }
+    if( ( start < lastblock ) )
+    {
+       if( verbose )
+           printf( "Unused gap of %8d sectors - sectors %8d-%d\n",
+                   lastblock - start, start, lastblock-1 );
+       gap += lastblock - start;
+       add2freelist( start, lastblock );
+    }
+    /*
+     * Done with arithmetics
+     * Go for details now
+     */
+    if( verbose )
+    {
+       if( !sgi_get_num_sectors( sgi_get_bootpartition() ) )
+       {
+           printf( "\nThe boot partition does not exist.\n" );
+       }
+       if( !sgi_get_num_sectors( sgi_get_swappartition() ) )
+       {
+           printf( "\nThe swap partition does not exist.\n" );
+       } else
+       if( ( sgi_get_sysid( sgi_get_swappartition() ) != SGI_SWAP )
+       &&  ( sgi_get_sysid( sgi_get_swappartition() ) != LINUX_SWAP ) )
+       {
+           printf( "\nThe swap partition has no swap type.\n" );
+       }
+       if( sgi_check_bootfile( "/unix" ) )
+       {
+           printf( "\tYou have chosen an unusual boot file name.\n" );
+       }
+    }
+    return gap;
+}
+
+void
+sgi_change_sysid( int i, int sys )
+{
+    if( sgi_get_num_sectors(i) == 0 ) /* caught already before, ... */
+    {
+       printf("Sorry You may change the Tag of non-empty partitions.\n");
+       return;
+    }
+    if( ((sys != ENTIRE_DISK ) && (sys != SGI_VOLHDR))
+     && (sgi_get_start_sector(i)<1) )
+    {
+       read_chars(
+       "It is highly recommended that the partition at offset 0\n"
+       "is of type \"SGI volhdr\", the IRIX system will rely on it to\n"
+       "retrieve from its directory standalone tools like sash and fx.\n"
+       "Only the \"SGI volume\" entire disk section may violate this.\n"
+       "Type YES if you are sure about tagging this partition differently.\n" );
+       if (strcmp (line_ptr, "YES\n"))
+                    return;
+    }
+    sgilabel->partitions[i].id = SSWAP32(sys);
+    return;
+}
+
+int
+sgi_entire( void )
+{   /* returns partition index of first entry marked as entire disk */
+    int i=0;
+    for( i=0; i<16; i++ )
+       if( sgi_get_sysid(i) == SGI_VOLUME )
+           return i;
+    return -1;
+}
+
+int
+sgi_num_partitions( void )
+{
+    int i=0,
+       n=0;
+    for( i=0; i<16; i++ )
+       if( sgi_get_num_sectors(i)!=0 )
+           n++;
+    return n;
+}
+
+static
+void
+sgi_set_partition( int i, uint start, uint length, int sys )
+{
+    sgilabel->partitions[i].id =
+           SSWAP32( sys );
+    sgilabel->partitions[i].num_sectors =
+           SSWAP32( length );
+    sgilabel->partitions[i].start_sector =
+           SSWAP32( start );
+    changed[i] = 1;
+    if( sgi_gaps(0) < 0 )      /* rebuild freelist */
+    {
+       printf( "Do You know, You got a partition overlap on the disk?\n" );
+    }
+    return;
+}
+
+static
+void
+sgi_set_entire( void )
+{
+    int n;
+    for( n=10; n<partitions; n++ )
+    {
+       if(!sgi_get_num_sectors( n ) )
+       {
+           sgi_set_partition( n, 0, sgi_get_lastblock(), SGI_VOLUME );
+           break;
+       }
+    }
+    return;
+}
+
+static
+void
+sgi_set_volhdr( void )
+{
+    int n;
+    for( n=8; n<partitions; n++ )
+    {
+       if(!sgi_get_num_sectors( n ) )
+       {
+           /*
+            * 5 cylinders is an arbitrary value I like
+            * IRIX 5.3 stored files in the volume header
+            * (like sash, symmon, fx, ide) with ca. 3200
+            * sectors.
+            */
+           if( heads * sectors * 5 < sgi_get_lastblock() )
+               sgi_set_partition( n, 0, heads * sectors * 5, SGI_VOLHDR );
+           break;
+       }
+    }
+    return;
+}
+
+void
+sgi_delete_partition( int i )
+{
+    sgi_set_partition( i, 0, 0, 0 );
+    return;
+}
+
+void
+sgi_add_partition( int n, int sys )
+{
+    char mesg[48];
+    int first=0, last=0;
+
+    if( n == 10 ) {
+       sys = SGI_VOLUME;
+    } else if ( n == 8 ) {
+       sys = 0;
+    }
+    if( sgi_get_num_sectors(n) )
+    {
+       printf( "Partition %d is already defined.  Delete "
+               "it before re-adding it.\n", n + 1);
+       return;
+    }
+    if( (sgi_entire() == -1)
+    &&  (sys != SGI_VOLUME) )
+    {
+       printf( "Attempting to generate entire disk entry automatically.\n" );
+       sgi_set_entire();
+       sgi_set_volhdr();
+    }
+    if( (sgi_gaps() == 0)
+    &&  (sys != SGI_VOLUME) )
+    {
+       printf( "The entire disk is already covered with partitions.\n" );
+       return;
+    }
+    if( sgi_gaps() < 0 )
+    {
+       printf( "You got a partition overlap on the disk. Fix it first!\n" );
+       return;
+    }
+    sprintf(mesg, "First %s", str_units());
+    for(;;)
+    {
+       if(sys == SGI_VOLUME)
+       {
+           last = sgi_get_lastblock();
+           first = read_int(0, 0, last-1, 0, mesg);
+           if( first != 0 ) {
+               printf( "It is highly recommended that eleventh partition\n"
+                       "covers the entire disk and is of type `SGI volume'\n");
+           }
+       } else {
+           first = freelist[0].first;
+           last  = freelist[0].last;
+           first = read_int(scround(first), scround(first), scround(last)-1,
+                            0, mesg);
+       }
+       if (unit_flag)
+           first *= display_factor;
+       else
+           first = first; /* align to cylinder if you know how ... */
+       if( !last )
+           last = isinfreelist(first);
+       if( last == 0 ) {
+           printf( "You will get a partition overlap on the disk. "
+                   "Fix it first!\n" );
+       } else
+           break;
+    }
+    sprintf(mesg, " Last %s", str_units());
+    last = read_int(scround(first), scround(last)-1, scround(last)-1,
+                   scround(first), mesg)+1;
+    if (unit_flag)                                                   
+       last *= display_factor;                                     
+    else                                                             
+       last = last; /* align to cylinder if You know how ... */
+    if( (sys == SGI_VOLUME) && ( first != 0 || last != sgi_get_lastblock() ) )
+    {
+       printf( "It is highly recommended that eleventh partition\n"
+               "covers the entire disk and is of type `SGI volume'\n");
+    }
+    sgi_set_partition( n, first, last-first, sys );
+    return;
+}
+
+void
+create_sgilabel( void )
+{
+    struct hd_geometry geometry;
+    struct { int start;
+            int nsect;
+            int sysid; } old[4];
+    int i=0;
+    fprintf( stderr,
+       "Building a new SGI disklabel. Changes will remain in memory only,\n"
+       "until you decide to write them. After that, of course, the previous\n"
+       "content will be unrecoverable lost.\n\n");
+#if BYTE_ORDER == LITTLE_ENDIAN
+    other_endian = 1;
+#else
+    other_endian = 0;
+#endif
+#ifdef HDIO_REQ
+    if (!ioctl(fd, HDIO_REQ, &geometry))
+#else
+    if (!ioctl(fd, HDIO_GETGEO, &geometry))
+#endif
+    {
+       heads = geometry.heads;
+       sectors = geometry.sectors;
+       cylinders = geometry.cylinders;
+    }
+    for (i = 0; i < 4; i++)
+    {
+       old[i].sysid = 0;
+       if( valid_part_table_flag(buffer) )
+       {
+           if( part_table[i]->sys_ind )
+           {
+               old[i].sysid = part_table[i]->sys_ind;
+               old[i].start = get_start_sect( part_table[i] );
+               old[i].nsect = get_nr_sects( part_table[i] );
+               printf( "Trying to keep parameters of partition %d.\n", i );
+               if( debug )
+                   printf( "ID=%02x\tSTART=%d\tLENGTH=%d\n",
+                           old[i].sysid, old[i].start, old[i].nsect );
+           }
+       }
+    }
+    memset(buffer, 0, SECTOR_SIZE);
+    sgilabel->magic = SSWAP32(SGI_LABEL_MAGIC);
+    sgilabel->boot_part = SSWAP16(0);
+    sgilabel->swap_part = SSWAP16(1); strncpy(
+    sgilabel->boot_file , "/unix\0\0\0\0\0\0\0\0\0\0\0", 16 );
+    sgilabel->devparam.skew                    = (0);
+    sgilabel->devparam.gap1                    = (0);
+    sgilabel->devparam.gap2                    = (0);
+    sgilabel->devparam.sparecyl                        = (0);
+    sgilabel->devparam.pcylcount               = SSWAP16(geometry.cylinders);
+    sgilabel->devparam.head_vol0               = SSWAP16(0);
+    sgilabel->devparam.ntrks                   = SSWAP16(geometry.heads);
+                                               /* tracks/cylinder (heads) */
+    sgilabel->devparam.cmd_tag_queue_depth     = (0);
+    sgilabel->devparam.unused0                 = (0);
+    sgilabel->devparam.unused1                 = SSWAP16(0);
+    sgilabel->devparam.nsect                   = SSWAP16(geometry.sectors);
+                                               /* sectors/track */
+    sgilabel->devparam.bytes                   = SSWAP16(512);
+    sgilabel->devparam.ilfact                  = SSWAP16(1);
+    sgilabel->devparam.flags                   = SSWAP32(TRACK_FWD|\
+                                                       IGNORE_ERRORS|RESEEK);
+    sgilabel->devparam.datarate                        = SSWAP32(0);
+    sgilabel->devparam.retries_on_error                = SSWAP32(1);
+    sgilabel->devparam.ms_per_word             = SSWAP32(0);
+    sgilabel->devparam.xylogics_gap1           = SSWAP16(0);
+    sgilabel->devparam.xylogics_syncdelay      = SSWAP16(0);
+    sgilabel->devparam.xylogics_readdelay      = SSWAP16(0);
+    sgilabel->devparam.xylogics_gap2           = SSWAP16(0);
+    sgilabel->devparam.xylogics_readgate       = SSWAP16(0);
+    sgilabel->devparam.xylogics_writecont      = SSWAP16(0);
+    memset( &(sgilabel->directory), 0, sizeof(struct volume_directory)*15 );
+    memset( &(sgilabel->partitions), 0, sizeof(struct sgi_partition)*16 );
+    sgi_label  =  1;
+    partitions = 16;
+    volumes    = 15;
+    sgi_set_entire();
+    sgi_set_volhdr();
+    for (i = 0; i < 4; i++)
+    {
+       if( old[i].sysid )
+       {
+           sgi_set_partition( i, old[i].start, old[i].nsect, old[i].sysid );
+       }
+    }
+    return;
+}
+
+void
+sgi_set_ilfact( void )
+{
+    /* do nothing in the beginning */
+}
+
+void
+sgi_set_rspeed( void )
+{
+    /* do nothing in the beginning */
+}
+
+void
+sgi_set_pcylcount( void )
+{
+    /* do nothing in the beginning */
+}
+
+void
+sgi_set_xcyl( void )
+{
+    /* do nothing in the beginning */
+}
+
+void
+sgi_set_ncyl( void )
+{
+    /* do nothing in the beginning */
+}
+
+/* _____________________________________________________________
+ */
+
+sgiinfo*
+fill_sgiinfo( void )
+{
+    sgiinfo*info=calloc( 1, sizeof(sgiinfo) );
+    info->magic=SSWAP32(SGI_INFO_MAGIC);
+    info->b1=SSWAP32(-1);
+    info->b2=SSWAP16(-1);
+    info->b3=SSWAP16(1);
+    /* You may want to replace this string !!!!!!! */
+    strcpy( info->scsi_string, "IBM OEM 0662S12         3 30" );
+    strcpy( info->serial, "0000" );
+    info->check1816 = SSWAP16(18*256 +16 );
+    strcpy( info->installer, "Sfx version 5.3, Oct 18, 1994" );
+    return info;
+}
diff --git a/fdisk/fdisksgilabel.h b/fdisk/fdisksgilabel.h
new file mode 100644 (file)
index 0000000..6eb7293
--- /dev/null
@@ -0,0 +1,133 @@
+#include <linux/types.h>   /* for __u32 etc */
+/*
+ * Copyright (C) Andreas Neuper, Sep 1998.
+ *     This file may be modified and redistributed under
+ *     the terms of the GNU Public License.
+ */
+
+struct device_parameter { /* 48 bytes */
+       unsigned char  skew;
+       unsigned char  gap1;
+       unsigned char  gap2;
+       unsigned char  sparecyl;
+       unsigned short pcylcount;
+       unsigned short head_vol0;
+       unsigned short ntrks;   /* tracks in cyl 0 or vol 0 */
+       unsigned char  cmd_tag_queue_depth;
+       unsigned char  unused0;
+       unsigned short unused1;
+       unsigned short nsect;   /* sectors/tracks in cyl 0 or vol 0 */
+       unsigned short bytes;
+       unsigned short ilfact;
+       unsigned int   flags;           /* controller flags */
+       unsigned int   datarate;
+       unsigned int   retries_on_error;
+       unsigned int   ms_per_word;
+       unsigned short xylogics_gap1;
+       unsigned short xylogics_syncdelay;
+       unsigned short xylogics_readdelay;
+       unsigned short xylogics_gap2;
+       unsigned short xylogics_readgate;
+       unsigned short xylogics_writecont;
+};
+
+#define        SGI_VOLUME      0x06
+#define        SGI_EFS         0x07
+#define        SGI_SWAP        0x03
+#define        SGI_VOLHDR      0x00
+#define        ENTIRE_DISK     SGI_VOLUME
+/*
+ * controller flags
+ */
+#define        SECTOR_SLIP     0x01
+#define        SECTOR_FWD      0x02
+#define        TRACK_FWD       0x04
+#define        TRACK_MULTIVOL  0x08
+#define        IGNORE_ERRORS   0x10
+#define        RESEEK          0x20
+#define        ENABLE_CMDTAGQ  0x40
+
+typedef struct {
+       unsigned int   magic;        /* expect SGI_LABEL_MAGIC */
+       unsigned short boot_part;        /* active boot partition */
+       unsigned short swap_part;        /* active swap partition */
+       unsigned char  boot_file[16];    /* name of the bootfile */
+       struct device_parameter devparam;       /*  1 * 48 bytes */
+       struct volume_directory {               /* 15 * 16 bytes */
+               unsigned char vol_file_name[8]; /* an character array */
+               unsigned int  vol_file_start;   /* number of logical block */
+               unsigned int  vol_file_size;    /* number of bytes */
+       } directory[15];
+       struct sgi_partition {                  /* 16 * 12 bytes */
+               unsigned int num_sectors;       /* number of blocks */
+               unsigned int start_sector;      /* sector must be cylinder aligned */
+               unsigned int id;
+       } partitions[16];
+       unsigned int   csum;
+       unsigned int   fillbytes;
+} sgi_partition;
+
+typedef struct {
+       unsigned int   magic;           /* looks like a magic number */
+       unsigned int   a2;
+       unsigned int   a3;
+       unsigned int   a4;
+       unsigned int   b1;
+       unsigned short b2;
+       unsigned short b3;
+       unsigned int   c[16];
+       unsigned short d[3];
+       unsigned char  scsi_string[50];
+       unsigned char  serial[137];
+       unsigned short check1816;
+       unsigned char  installer[225];
+} sgiinfo;
+
+#define        SGI_LABEL_MAGIC         0x0be5a941
+#define        SGI_LABEL_MAGIC_SWAPPED 0x41a9e50b
+#define        SGI_INFO_MAGIC          0x00072959
+#define        SGI_INFO_MAGIC_SWAPPED  0x59290700
+#define SSWAP16(x) (other_endian ? __swap16(x) \
+                                 : (__u16)(x))
+#define SSWAP32(x) (other_endian ? __swap32(x) \
+                                 : (__u32)(x))
+#define scround(x) ((x+(display_factor-1)*unit_flag)/display_factor)
+
+/* fdisk.c */
+#define sgilabel ((sgi_partition *)buffer)
+#define sgiparam (sgilabel->devparam)
+extern char buffer[MAX_SECTOR_SIZE];
+extern char changed[MAXIMUM_PARTS];
+extern uint heads, sectors, cylinders;
+extern int show_begin;
+extern int sgi_label;
+extern char *partition_type(unsigned char type);
+extern void update_units(void);
+extern char read_chars(char *mesg);
+
+/* fdisksgilabel.c */
+extern struct  systypes sgi_sys_types[];
+extern void    sgi_nolabel( void );
+extern int     check_sgi_label( void );
+extern void    sgi_list_table( int xtra );
+extern void    sgi_change_sysid( int i, int sys );
+extern int     sgi_get_start_sector( int i );
+extern int     sgi_get_num_sectors( int i );
+extern int     sgi_get_sysid( int i );
+extern void    sgi_delete_partition( int i );
+extern void    sgi_add_partition( int n, int sys );
+extern void    create_sgilabel( void );
+extern void    create_sgiinfo( void );
+extern int     verify_sgi( int verbose );
+extern void    sgi_write_table( void );
+extern void    sgi_set_ilfact( void );
+extern void    sgi_set_rspeed( void );
+extern void    sgi_set_pcylcount( void );
+extern void    sgi_set_xcyl( void );
+extern void    sgi_set_ncyl( void );
+extern void    sgi_set_bootpartition( int i );
+extern void    sgi_set_swappartition( int i );
+extern int     sgi_get_bootpartition( void );
+extern int     sgi_get_swappartition( void );
+extern void    sgi_set_bootfile( const char* aFile );
+extern const char *sgi_get_bootfile( void );
similarity index 73%
rename from disk-utils/fdisksunlabel.c
rename to fdisk/fdisksunlabel.c
index a5a87b8d45e33533b4a7c8fda8f7048b71b07084..70837737919b006ae594a3fa45e5ea2b2f831523 100644 (file)
@@ -6,7 +6,6 @@
  *
  * Merged with fdisk for other architectures, aeb, June 1998.
  */
-#if defined (sparc)
 
 #include <stdio.h>             /* stderr */
 #include <stdlib.h>            /* uint */
 #include <sys/stat.h>          /* stat */
 
 #include <endian.h>
-#include <scsi/scsi.h>
+#if 1
+#include <scsi/scsi.h>         /* SCSI_IOCTL_GET_IDLUN */
+#endif
 #include <linux/major.h>       /* FLOPPY_MAJOR */
 #include <linux/hdreg.h>       /* HDIO_GETGEO */
 
 #include "fdisk.h"
 #include "fdisksunlabel.h"
 
-int     other_endian = 0;
-int     scsi_disk = 0;
-int     floppy = 0;
+static int     other_endian = 0;
+static int     scsi_disk = 0;
+static int     floppy = 0;
 
 #define LINUX_SWAP      0x82
 #define LINUX_NATIVE    0x83
@@ -45,10 +46,10 @@ struct systypes sun_sys_types[] = {
        { 0, NULL }
 };
 
-inline unsigned short __swap16(unsigned short x) {
+static inline unsigned short __swap16(unsigned short x) {
         return (((__u16)(x) & 0xFF) << 8) | (((__u16)(x) & 0xFF00) >> 8);
 }
-inline __u32 __swap32(__u32 x) {
+static inline __u32 __swap32(__u32 x) {
         return (((__u32)(x) & 0xFF) << 24) | (((__u32)(x) & 0xFF00) << 8) | (((__u32)(x) & 0xFF0000) >> 8) | (((__u32)(x) & 0xFF000000) >> 24);
 }
 
@@ -88,12 +89,20 @@ void set_sun_partition(int i, uint start, uint stop, int sysid)
        changed[i] = 1;
 }
 
+void sun_nolabel(void)
+{
+       sun_label = 0;
+       sunlabel->magic = 0;
+       partitions = 4;
+}
+
 int check_sun_label(void)
 {
        unsigned short *ush;
        int csum;
        
-       if (sunlabel->magic != SUN_LABEL_MAGIC && sunlabel->magic != SUN_LABEL_MAGIC_SWAPPED) {
+       if (sunlabel->magic != SUN_LABEL_MAGIC &&
+           sunlabel->magic != SUN_LABEL_MAGIC_SWAPPED) {
                sun_label = 0;
                other_endian = 0;
                return 0;
@@ -145,6 +154,74 @@ struct sun_predefined_drives {
 {"IOMEGA","Jaz",0,1019,2,1021,64,32,5394},
 };
 
+struct sun_predefined_drives *
+sun_autoconfigure_scsi() {
+    struct sun_predefined_drives *p = NULL;
+
+#ifdef SCSI_IOCTL_GET_IDLUN
+    unsigned int id[2];
+    char buffer[2048];
+    char buffer2[2048];
+    FILE *pfd;
+    char *vendor;
+    char *model;
+    char *q;
+    int i;
+
+    if (!ioctl(fd, SCSI_IOCTL_GET_IDLUN, &id)) {
+        sprintf(buffer,
+            "Host: scsi%d Channel: %02d Id: %02d Lun: %02d\n",
+#if 0                    
+            ((id[0]>>24)&0xff)-/*PROC_SCSI_SCSI+PROC_SCSI_FILE*/33,
+#else
+            /* This is very wrong (works only if you have one HBA),
+               but I haven't found a way how to get hostno
+               from the current kernel */
+            0,
+#endif                        
+            (id[0]>>16)&0xff,
+            id[0]&0xff,
+            (id[0]>>8)&0xff);
+        pfd = fopen("/proc/scsi/scsi","r");
+        if (pfd) {
+            while (fgets(buffer2,2048,pfd)) {
+                            if (!strcmp(buffer, buffer2)) {
+                    if (fgets(buffer2,2048,pfd)) {
+                        q = strstr(buffer2,"Vendor: ");
+                        if (q) {
+                            q += 8;
+                            vendor = q;
+                            q = strstr(q," Model: ");
+                            if (q) {
+                                *q = 0;
+                                q += 8;
+                                model = q;
+                                q = strstr(q," Rev: ");
+                                if (q) {
+                                    *q = 0;
+                                    for (i = 0; i < SIZE(sun_drives); i++) {
+                                        if (*sun_drives[i].vendor && strcasecmp(sun_drives[i].vendor, vendor))
+                                            continue;
+                                        if (!strstr(model, sun_drives[i].model))
+                                            continue;
+                                        printf("Autoconfigure found a %s%s%s\n",sun_drives[i].vendor,(*sun_drives[i].vendor) ? " " : "",sun_drives[i].model);
+                                        p = sun_drives + i;
+                                        break;
+                                    }
+                                }
+                            }
+                        }
+                    }
+                    break;
+                }
+            }
+            fclose(pfd);
+        }
+    }
+#endif
+    return p;
+}
+
 void create_sunlabel(void)
 {
        struct hd_geometry geometry;
@@ -181,64 +258,10 @@ void create_sunlabel(void)
                } else if (c >= 'A' && c < 'A' + SIZE(sun_drives)) {
                    p = sun_drives + c - 'A';
                    break;
-               } else if (c == '0')
+               } else if (c == '0') {
                    break;
-               else if (c == '?' && scsi_disk) {
-                   unsigned int id[2];
-                   char buffer[2048];
-                   char buffer2[2048];
-                   FILE *pfd;
-                   char *vendor;
-                   char *model;
-                   char *q;
-                   
-                   if (!ioctl(fd, SCSI_IOCTL_GET_IDLUN, &id)) {
-                       sprintf(buffer, "Host: scsi%d Channel: %02d Id: %02d Lun: %02d\n",
-#if 0                  
-                           ((id[0]>>24)&0xff)-/*PROC_SCSI_SCSI+PROC_SCSI_FILE*/33,
-#else
-                       /* This is very wrong (works only if you have one HBA), but I haven't find a way how to get hostno from the current kernel */
-                           0,
-#endif                     
-                           (id[0]>>16)&0xff,
-                           id[0]&0xff,
-                           (id[0]>>8)&0xff);
-                       pfd = fopen("/proc/scsi/scsi","r");
-                       if (pfd) {
-                           while (fgets(buffer2,2048,pfd)) {
-                               if (!strcmp(buffer, buffer2)) {
-                                   if (fgets(buffer2,2048,pfd)) {
-                                       q = strstr(buffer2,"Vendor: ");
-                                       if (q) {
-                                           q += 8;
-                                           vendor = q;
-                                           q = strstr(q," Model: ");
-                                           if (q) {
-                                               *q = 0;
-                                               q += 8;
-                                               model = q;
-                                               q = strstr(q," Rev: ");
-                                               if (q) {
-                                                   *q = 0;
-                                                   for (i = 0; i < SIZE(sun_drives); i++) {
-                                                       if (*sun_drives[i].vendor && strcasecmp(sun_drives[i].vendor, vendor))
-                                                           continue;
-                                                       if (!strstr(model, sun_drives[i].model))
-                                                           continue;
-                                                       printf("Autoconfigure found a %s%s%s\n",sun_drives[i].vendor,(*sun_drives[i].vendor) ? " " : "",sun_drives[i].model);
-                                                       p = sun_drives + i;
-                                                       break;
-                                                   }
-                                               }
-                                           }
-                                       }
-                                   }
-                                   break;
-                               }
-                           }
-                           fclose(pfd);
-                       }
-                   }
+               } else if (c == '?' && scsi_disk) {
+                   p = sun_autoconfigure_scsi();
                    if (!p)
                        printf("Autoconfigure failed.\n");
                    else
@@ -267,23 +290,26 @@ void create_sunlabel(void)
                sunlabel->ilfact = SSWAP16(1);
                sunlabel->sparecyl = 0;
            } else {
-               if (heads)
-                   heads = read_int(1,heads,1024,deflt,"Heads");
-               else
-                   heads = read_int(1,1,1024,ignore,"Heads");
-               if (sectors)
-                   sectors = read_int(1,sectors,1024,deflt,"Sectors/track");
-               else
-                   sectors = read_int(1,1,1024,ignore,"Sectors/track");
+               heads = read_int(1,heads,1024,0,"Heads");
+               sectors = read_int(1,sectors,1024,0,"Sectors/track");
                if (cylinders)
-                   cylinders = read_int(1,cylinders-2,65535,deflt,"Cylinders");
+                   cylinders = read_int(1,cylinders-2,65535,0,"Cylinders");
                else
-                   cylinders = read_int(1,1,65535,ignore,"Cylinders");
-               sunlabel->nacyl = SSWAP16(read_int(0,2,65535,deflt,"Alternate cylinders"));
-               sunlabel->pcylcount = SSWAP16(read_int(0,cylinders + SSWAP16(sunlabel->nacyl),65535,deflt,"Physical cylinders"));
-               sunlabel->rspeed = SSWAP16(read_int(1,5400,100000,deflt,"Rotation speed (rpm)"));
-               sunlabel->ilfact = SSWAP16(read_int(1,1,32,deflt,"Interleave factor"));
-               sunlabel->sparecyl = SSWAP16(read_int(0,0,sectors,deflt,"Extra sectors per cylinder"));
+                   cylinders = read_int(1,0,65535,0,"Cylinders");
+               sunlabel->nacyl =
+                       SSWAP16(read_int(0,2,65535,0,
+                                        "Alternate cylinders"));
+               sunlabel->pcylcount =
+                       SSWAP16(read_int(0,cylinders+SSWAP16(sunlabel->nacyl),
+                                        65535,0,"Physical cylinders"));
+               sunlabel->rspeed =
+                       SSWAP16(read_int(1,5400,100000,0,
+                                        "Rotation speed (rpm)"));
+               sunlabel->ilfact =
+                       SSWAP16(read_int(1,1,32,0,"Interleave factor"));
+               sunlabel->sparecyl =
+                       SSWAP16(read_int(0,0,sectors,0,
+                                        "Extra sectors per cylinder"));
            }
        } else {
            sunlabel->sparecyl = SSWAP16(p->sparecyl);
@@ -459,18 +485,22 @@ void add_sun_partition(int n, int sys)
        sprintf(mesg, "First %s", str_units());
        for (;;) {
                if (whole_disk)
-                       first = read_int(0, 0, 0, deflt, mesg);
+                       first = read_int(0, 0, 0, 0, mesg);
                else
-                       first = read_int(scround(start), scround(start), scround(stop),
-                                        ignore, mesg);
+                       first = read_int(scround(start), scround(stop)+1,
+                                        scround(stop), 0, mesg);
                if (unit_flag)
                        first *= display_factor;
                else
-                       first = (first + heads * sectors - 1) / (heads * sectors); /* Starting sector has to be properly aligned */
-               if (n == 2 && first != 0) printf ("It is highly recommended that third partition covers the whole disk\n"
-                                                 "and is of type `Whole disk'\n");
+                       /* Starting sector has to be properly aligned */
+                       first = (first + heads * sectors - 1) / (heads * sectors);
+               if (n == 2 && first != 0)
+                       printf ("\
+It is highly recommended that the third partition covers the whole disk\n\
+and is of type `Whole disk'\n");
                for (i = 0; i < partitions; i++)
-                       if (lens[i] && starts[i] <= first && starts[i] + lens[i] > first)
+                       if (lens[i] && starts[i] <= first
+                                   && starts[i] + lens[i] > first)
                                break;
                if (i < partitions && !whole_disk) {
                        if (n == 2 && !first) {
@@ -489,14 +519,14 @@ void add_sun_partition(int n, int sys)
        }
        sprintf(mesg, "Last %s or +size or +sizeM or +sizeK", str_units());
        if (whole_disk)
-               last = read_int(scround(stop2), scround(stop2), scround(stop2), 
-                               deflt, mesg);
+               last = read_int(scround(stop2), scround(stop2), scround(stop2),
+                               0, mesg);
        else if (n == 2 && !first)
                last = read_int(scround(first), scround(stop2), scround(stop2),
-                               upper, mesg);
+                               scround(first), mesg);
        else
                last = read_int(scround(first), scround(stop), scround(stop),
-                               lower, mesg);
+                               scround(first), mesg);
        if (unit_flag)
                last *= display_factor;
        if (n == 2 && !first) {
@@ -520,10 +550,13 @@ void
 sun_delete_partition(int i) {
        if (i == 2 && sunlabel->infos[i].id == WHOLE_DISK && 
            !sunlabel->partitions[i].start_cylinder && 
-           SSWAP32(sunlabel->partitions[i].num_sectors) == heads * sectors * cylinders)
-               printf("If you want to maintain SunOS/Solaris compatibility, consider leaving this\n"
-                      "partition as Whole disk (5), starting at 0, with %d sectors\n",
-                      SSWAP32(sunlabel->partitions[i].num_sectors));
+           SSWAP32(sunlabel->partitions[i].num_sectors)
+             == heads * sectors * cylinders)
+               printf("If you want to maintain SunOS/Solaris compatibility, "
+                      "consider leaving this\n"
+                      "partition as Whole disk (5), starting at 0, with %u "
+                      "sectors\n",
+                      (uint) SSWAP32(sunlabel->partitions[i].num_sectors));
        sunlabel->infos[i].id = 0;
        sunlabel->partitions[i].num_sectors = 0;
 }
@@ -580,23 +613,20 @@ sun_list_table(int xtra) {
                       disk_device, heads, sectors, cylinders,
                       str_units(), display_factor);
 
-       printf("%*s Flag %s  Start      End   Blocks   Id  System\n",
-              w + 1, "Device", show_begin ? "  Begin  " : " ");
+       printf("%*s Flag     Start       End    Blocks   Id  System\n",
+              w + 1, "Device");
        for (i = 0 ; i < partitions; i++) {
                if (sunlabel->partitions[i].num_sectors) {
                        __u32 start = SSWAP32(sunlabel->partitions[i].start_cylinder) * heads * sectors;
                        __u32 len = SSWAP32(sunlabel->partitions[i].num_sectors);
                        printf(
-                         show_begin
-                           ? "%*s%-2d %c%c%9d%9d%9d%9d%c  %2x  %s\n"
-                           : "%*s%-2d %c%c%c%9d%9d%9d%c  %2x  %s\n",
+                           "%*s%-2d %c%c %9ld %9ld %9ld%c  %2x  %s\n",
 /* device */             w, disk_device, i + 1,
 /* flags */              (sunlabel->infos[i].flags & 0x01) ? 'u' : ' ',
                          (sunlabel->infos[i].flags & 0x10) ? 'r' : ' ',
-/* begin */              show_begin ? scround(start) : ' ',
-/* start */              scround(start),
-/* end */                scround(start+len),
-/* odd flag on end */    len / 2, len & 1 ? '+' : ' ',
+/* start */              (long) scround(start),
+/* end */                (long) scround(start+len),
+/* odd flag on end */    (long) len / 2, len & 1 ? '+' : ' ',
 /* type id */            sunlabel->infos[i].id,
 /* type name */                  (type = partition_type(sunlabel->infos[i].id))
                                ? type : "Unknown");
@@ -606,9 +636,9 @@ sun_list_table(int xtra) {
 
 void
 sun_set_alt_cyl(void) {
-       sunlabel->nacyl = SSWAP16(read_int(0,SSWAP16(sunlabel->nacyl),
-                                          65535, deflt,
-                                          "Number of alternate cylinders"));
+       sunlabel->nacyl =
+               SSWAP16(read_int(0,SSWAP16(sunlabel->nacyl), 65535, 0,
+                                "Number of alternate cylinders"));
 }
 
 void
@@ -618,30 +648,30 @@ sun_set_ncyl(int cyl) {
 
 void
 sun_set_xcyl(void) {
-       sunlabel->sparecyl = SSWAP16(read_int(0, SSWAP16(sunlabel->sparecyl),
-                                             sectors, deflt,
-                                             "Extra sectors per cylinder"));
+       sunlabel->sparecyl =
+               SSWAP16(read_int(0, SSWAP16(sunlabel->sparecyl), sectors, 0,
+                                "Extra sectors per cylinder"));
 }
 
 void
 sun_set_ilfact(void) {
-       sunlabel->ilfact = SSWAP16(read_int(1, SSWAP16(sunlabel->ilfact),
-                                           32, deflt,
-                                           "Interleave factor"));
+       sunlabel->ilfact =
+               SSWAP16(read_int(1, SSWAP16(sunlabel->ilfact), 32, 0,
+                                "Interleave factor"));
 }
 
 void
 sun_set_rspeed(void) {
-       sunlabel->rspeed = SSWAP16(read_int(1, SSWAP16(sunlabel->rspeed),
-                                           100000, deflt,
-                                           "Rotation speed (rpm)"));
+       sunlabel->rspeed =
+               SSWAP16(read_int(1, SSWAP16(sunlabel->rspeed), 100000, 0,
+                                "Rotation speed (rpm)"));
 }
 
 void
 sun_set_pcylcount(void) {
-       sunlabel->pcylcount=SSWAP16(read_int(0, SSWAP16(sunlabel->pcylcount),
-                                            65535, deflt,
-                                            "Number of physical cylinders"));
+       sunlabel->pcylcount =
+               SSWAP16(read_int(0, SSWAP16(sunlabel->pcylcount), 65535, 0,
+                                "Number of physical cylinders"));
 }
 
 void
@@ -658,4 +688,3 @@ sun_write_table(void) {
                fatal(unable_to_write);
 }
 
-#endif /* sparc */
similarity index 97%
rename from disk-utils/fdisksunlabel.h
rename to fdisk/fdisksunlabel.h
index 037e437c6756979e8a0846045c9eae5b76c5005a..d9d3706d30e804c09445c9e3b8a10129ef054f76 100644 (file)
@@ -40,7 +40,7 @@ typedef struct {
 
 /* fdisk.c */
 extern char changed[MAXIMUM_PARTS];
-extern char buffer[SECTOR_SIZE];
+extern char buffer[MAX_SECTOR_SIZE];
 extern uint heads, sectors, cylinders;
 extern int show_begin;
 extern int sun_label;
@@ -56,6 +56,7 @@ extern struct systypes sun_sys_types[];
 extern int get_num_sectors(struct sun_partition p);
 extern void guess_device_type(int fd);
 extern int check_sun_label(void);
+extern void sun_nolabel(void);
 extern void create_sunlabel(void);
 extern void sun_delete_partition(int i);
 extern void sun_change_sysid(int i, int sys);
similarity index 100%
rename from disk-utils/llseek.c
rename to fdisk/llseek.c
similarity index 97%
rename from disk-utils/sfdisk.8
rename to fdisk/sfdisk.8
index 33f10dabd7058611d16370f4dd40928d71df904b..e7f3e82b68d25b8e545f6787d56efea2401ae49d 100644 (file)
@@ -120,6 +120,7 @@ As a precaution, one can save the sectors changed by
 .nf
 .if t .ft CW
 % sfdisk /dev/hdd \-O hdd-partition-sectors.save
+\&...
 %
 .if t .ft R
 .fi
@@ -136,6 +137,14 @@ the old situation with
 .if t .ft R
 .fi
 .RE
+.LP
+(This is not the same as saving the old partition table:
+a readable version of the old partition table can be saved
+using the \-d option. However, if you create logical partitions,
+the sectors describing them are located somewhere on disk,
+possibly on sectors that were not part of the partition table
+before. Thus, the information the \-O option saves is not a binary
+version of the output of \-d.)
 
 There are many options.
 
@@ -195,7 +204,7 @@ and change nothing else. (Probably this fifth partition
 is called /dev/hdb5, but you are free to call it something else,
 like `/my_equipment/disks/2/5' or so).
 .TP
-.BI \-A " number"
+.BI \-A "number"
 Make the indicated partition(s) active, and all others inactive.
 .TP
 .BI \-c " or " \-\-id " number [Id]"
similarity index 98%
rename from disk-utils/sfdisk.c
rename to fdisk/sfdisk.c
index 8fbe778fea097ff914135d3c182ed37c2d8c6139..c3f470f895174aa60480df6c0440a88ca63132da 100644 (file)
@@ -610,6 +610,7 @@ struct systypes {
     {0xe1, "DOS access or SpeedStor 12-bit FAT extended partition"},
     {0xe3, "DOS R/O or SpeedStor"},
     {0xe4, "SpeedStor 16-bit FAT extended partition < 1024 cyl."},
+    {0xeb, "BeOS fs"},
     {0xf1, "SpeedStor"},
     {0xf2, "DOS 3.3+ secondary"},
     {0xf4, "SpeedStor large partition"},
@@ -2254,7 +2255,8 @@ static struct devd {
 } defdevs[] = {
     { "hd", "abcdefgh" },
     { "sd", "abcde" },
-    { "xd", "ab" }
+    { "xd", "ab" },
+    { "ed", "abcd" }
 };
 
 int
@@ -2315,10 +2317,10 @@ main(int argc, char **argv) {
     else
       progn++;
     if (!strcmp(progn, "activate"))
-      activate = 1;            /* equivalent to `fdisk -A' */
+      activate = 1;            /* equivalent to `sfdisk -A' */
 #if 0                          /* not important enough to deserve a name */
     else if (!strcmp(progn, "unhide"))
-      unhide = 1;              /* equivalent to `fdisk -U' */
+      unhide = 1;              /* equivalent to `sfdisk -U' */
 #endif
     else
       fdisk = 1;
@@ -2439,9 +2441,9 @@ main(int argc, char **argv) {
 
     if (optind == argc) {
        if (activate)
-         activate_usage(fdisk ? "fdisk -A" : progn);
+         activate_usage(fdisk ? "sfdisk -A" : progn);
        else if (unhide)
-         unhide_usage(fdisk ? "fdisk -U" : progn);
+         unhide_usage(fdisk ? "sfdisk -U" : progn);
        else
          usage();
     }
@@ -2469,11 +2471,11 @@ main(int argc, char **argv) {
     }
     if (do_id) {
         if ((do_id & PRINT_ID) != 0 && optind != argc-2)
-         fatal("usage: fdisk --print-id device partition-number\n");
+         fatal("usage: sfdisk --print-id device partition-number\n");
        else if ((do_id & CHANGE_ID) != 0 && optind != argc-3)
-         fatal("usage: fdisk --change-id device partition-number Id\n");
+         fatal("usage: sfdisk --change-id device partition-number Id\n");
        else if (optind != argc-3 && optind != argc-2)
-         fatal("usage: fdisk --id device partition-number [Id]\n");
+         fatal("usage: sfdisk --id device partition-number [Id]\n");
        do_change_id(argv[optind], argv[optind+1],
                     (optind == argc-2) ? 0 : argv[optind+2]);
        exit(exit_status);
@@ -2571,6 +2573,11 @@ do_size (char *dev, int silent) {
     }
 
     size /= 2;                 /* convert sectors to blocks */
+
+    /* a CDROM drive without mounted CD yields MAXINT */
+    if (silent && size == ((1<<30)-1))
+      return;
+
     if (silent)
       printf("%s: %9d\n", dev, size);
     else
@@ -2586,15 +2593,15 @@ do_size (char *dev, int silent) {
  *
  * Call: activate /dev/hda 2 5 7       make these partitions active
  *                                     and the remaining ones inactive
- * Or:   fdisk -A /dev/hda 2 5 7
+ * Or:   sfdisk -A /dev/hda 2 5 7
  *
  * If only a single partition must be active, one may also use the form
- *       fdisk -A2 /dev/hda
+ *       sfdisk -A2 /dev/hda
  *
- * With "activate /dev/hda" or "fdisk -A /dev/hda" the active partitions
+ * With "activate /dev/hda" or "sfdisk -A /dev/hda" the active partitions
  * are listed but not changed. To get zero active partitions, use
- * "activate /dev/hda none" or "fdisk -A /dev/hda none".
- * Use something like `echo ",,,*" | fdisk -N2 /dev/hda' to only make
+ * "activate /dev/hda none" or "sfdisk -A /dev/hda none".
+ * Use something like `echo ",,,*" | sfdisk -N2 /dev/hda' to only make
  * /dev/hda2 active, without changing other partitions.
  *
  * A warning will be given if after the change not precisely one primary
@@ -2825,7 +2832,7 @@ Use the --no-reread flag to suppress this check.\n");
            while (c != '\n' && c != EOF)
              c = getchar();
            if (c == EOF)
-               printf("\nfdisk: premature end of input\n");
+               printf("\nsfdisk: premature end of input\n");
            if (c == EOF || answer == 'q' || answer == 'Q') {
                fatal("Quitting - nothing changed\n");
            } else if (answer == 'n' || answer == 'N') {
index 49b9f981f24196f51d18b5937aaa2a5e862ccc58..58a8f8f6b1718225b6342fdd33dd7ae1d3ee53af 100644 (file)
@@ -20,7 +20,7 @@ all: $(USRGAMES)
 
 # Rules for everything else
 
-banner: banner.o $(BSD)/getopt.o $(BSD)/err.o
+banner: banner.o $(ERR_O)
 ddate: ddate.o
 
 install: all
similarity index 100%
rename from getopt/COPYING
rename to getopt-1.0.3a/COPYING
similarity index 53%
rename from getopt/Changelog
rename to getopt-1.0.3a/Changelog
index 0480a1dedbdf574ff234e3fd9edc8730924c7c08..24a4c3235db59d39249cf9c3ba8660c21401ede7 100644 (file)
@@ -1,3 +1,9 @@
+980628: Bumped up version number to 1.0.3
+980628: Removed remaining incompatibility with tcsh-6.02 from parse.tcsh
+980626: Added separate Makefile for util-linux
+980625: Removed several bugs from parse.tcsh, partly thanks to Volker Kuhlmann
+        (v.kuhlmann@elec.canterbury.ac.nz).
+980612: Removed reference to getopt in util-linux
 980611: Bumped up version number to 1.0.2
 980611: Fixed --version bug (was not available, though documented!)
 980611: Removed compiler warnings.
diff --git a/getopt-1.0.3a/Makefile b/getopt-1.0.3a/Makefile
new file mode 100644 (file)
index 0000000..0d4a5ad
--- /dev/null
@@ -0,0 +1,52 @@
+.SUFFIXES:
+
+include ../MCONFIG
+
+GETOPTDIR=$(USRLIBDIR)/getopt
+
+# Define this to 0 to use the getopt(3) routines in this package.
+LIBCGETOPT=1
+
+SHELL=/bin/sh
+
+LD=ld
+RM=rm -f
+INSTALL=install
+
+CPPFLAGS=-DLIBCGETOPT=$(LIBCGETOPT)
+ifeq ($(LIBCGETOPT),0)
+CPPFLAGS+=-I./gnu
+endif
+
+# -Wcast-align causes problems with the identifier stderr on alpha's
+# with an old glibc.
+# -Wbad-function-cast and -Wmissing-declarations are unknown for gcc 2.5.8.
+WARNINGS=-Wall \
+         -W -Wshadow -Wpointer-arith -Wcast-qual \
+         -Wwrite-strings -Wstrict-prototypes -Wmissing-prototypes \
+         -Wnested-externs -Winline
+CFLAGS=$(WARNINGS) $(OPT)
+
+SOURCES=getopt.c
+ifeq ($(LIBCGETOPT),0)
+SOURCES+=gnu/getopt.c gnu/getopt1.c
+endif
+
+OBJECTS=$(SOURCES:.c=.o)
+
+BINARIES=getopt
+
+.PHONY: all clean realclean 
+all: $(BINARIES)
+
+clean:
+       -$(RM) $(OBJECTS) $(BINARIES) 
+
+getopt: $(OBJECTS)
+       $(CC) $(LDFLAGS) $< -o $@
+
+install: getopt
+       $(INSTALLDIR) $(USRBINDIR) $(MAN1DIR) $(GETOPTDIR)
+       $(INSTALLBIN) getopt $(USRBINDIR)
+       $(INSTALLMAN) getopt.1 $(MAN1DIR)
+       $(INSTALLBIN) parse.bash parse.tcsh test.bash test.tcsh $(GETOPTDIR)
similarity index 93%
rename from getopt/README
rename to getopt-1.0.3a/README
index 04addba98d49d1a5e50feaa0b53c80a39893b7f3..1d795f5e471d2f11392bc32c210a753fe9ec695f 100644 (file)
@@ -3,9 +3,9 @@ This package contains a reimplementation of getopt(1).
 PREFACE
 
 Getopt(1) is a program to help shell scripts parse command-line parameters.
-It is for example included in the util-linux distribution. But, there are
-some problems with that getopt(1) implementation, as listed in the
-'BUGS' section of its man-page:
+It is for example included in the util-linux distribution (upto version
+2.7.1). But, there are some problems with that getopt(1) implementation, 
+as listed in the 'BUGS' section of its man-page:
 
 >BUGS
 >     Whatever getopt(3) has.
similarity index 83%
rename from getopt/TODO
rename to getopt-1.0.3a/TODO
index e701f6661b5287622cd5006f87a390e2ca2ea20d..70f2ea9cb5c55e81c1edf5c9ada2a8977f365f5b 100644 (file)
@@ -2,3 +2,5 @@ Other shells, like zsh and ash, should be supported (perhaps they will work
 already, depending on quoting conventions). (zsh seems OK).
 
 Perhaps a nice configure script?
+
+Add a `test' target in Makefile.
similarity index 100%
rename from getopt/getopt.1
rename to getopt-1.0.3a/getopt.1
similarity index 99%
rename from getopt/getopt.c
rename to getopt-1.0.3a/getopt.c
index 00be49f3432361de3caaf5cab332a94a449e785a..de643f1a7c62241297cdf8ca876d71ce09631f94 100644 (file)
@@ -358,7 +358,7 @@ int main(int argc, char *argv[])
 {
        char *optstr=NULL;
        char *name=NULL;
-       char opt;
+       int opt;
        int compatible=0;
 
        init_longopt();
@@ -421,7 +421,7 @@ int main(int argc, char *argv[])
                case 'T':
                        exit(4);
                case 'V':
-                       printf("getopt (enhanced) 1.0.2\n");
+                       printf("getopt (enhanced) 1.0.3\n");
                        exit(0);
                case '?':
                case ':':
similarity index 100%
rename from getopt/parse.bash
rename to getopt-1.0.3a/parse.bash
similarity index 83%
rename from getopt/parse.tcsh
rename to getopt-1.0.3a/parse.tcsh
index 7d4f42719e4f535ce03dc8149d365f4649fd5855..2266d0e648f01f5dce34496b7f5311e3ef56e41b 100644 (file)
@@ -1,9 +1,9 @@
 #!/bin/tcsh
 
 # A small example program for using the new getopt(1) program.
-# This program will only work with bash(1)
-# An similar program using the tcsh(1) script language can be found
-# as parse.tcsh
+# This program will only work with tcsh(1)
+# An similar program using the bash(1) script language can be found
+# as parse.bash
 
 # Example input and output (from the tcsh prompt):
 # ./parse.tcsh -a par1 'another arg' --c-long 'wow\!*\?' -cmore -b " very long "
@@ -37,8 +37,6 @@ endif
 # The 'q` stops doing any silly substitutions.
 eval set argv=\($temp:q\)
 
-set
-
 while (1)
        switch($1:q)
        case -a:
@@ -47,7 +45,7 @@ while (1)
                breaksw;
        case -b:
        case --b-long:
-               echo "Option b, argument "\`$2\' ; shift ; shift
+               echo "Option b, argument "\`$2:q\' ; shift ; shift
                breaksw
        case -c:
        case --c-long:
@@ -58,7 +56,7 @@ while (1)
                if ($2:q == "") then
                        echo "Option c, no argument"
                else
-                       echo "Option c, argument "\`$2\'
+                       echo "Option c, argument "\`$2:q\'
                endif
                shift; shift
                breaksw
@@ -71,6 +69,9 @@ while (1)
 end
 
 echo "Remaining arguments:"
-foreach el ($argv:q)
-       echo '--> '\`$el:q\'
+# foreach el ($argv:q) created problems for some tcsh-versions (at least
+# 6.02). So we use another shift-loop here:
+while ($#argv > 0)
+       echo '--> '\`$1:q\'
+       shift
 end
similarity index 100%
rename from getopt/test.bash
rename to getopt-1.0.3a/test.bash
similarity index 100%
rename from getopt/test.tcsh
rename to getopt-1.0.3a/test.tcsh
diff --git a/getopt/Makefile b/getopt/Makefile
deleted file mode 100644 (file)
index 368291f..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-.SUFFIXES:
-
-include ../MCONFIG
-
-prefix=$(DESTDIR)/usr
-bindir=$(USRBINDIR)
-mandir=$(MANDIR)
-man1dir=$(MAN1DIR)/man1
-getoptdir=$(USRLIBDIR)/getopt
-
-# Define this to 0 to use the getopt(3) routines in this package.
-LIBCGETOPT=1
-
-SHELL=/bin/sh
-
-LD=ld
-RM=rm -f
-INSTALL=install
-
-CPPFLAGS=-DLIBCGETOPT=$(LIBCGETOPT)
-ifeq ($(LIBCGETOPT),0)
-CPPFLAGS+=-I./gnu
-endif
-WARNINGS=-Wall \
-         -W -Wshadow -Wpointer-arith -Wbad-function-cast -Wcast-qual \
-         -Wcast-align -Wmissing-declarations \
-         -Wwrite-strings -Wstrict-prototypes -Wmissing-prototypes \
-         -Wnested-externs -Winline
-CFLAGS=$(WARNINGS) $(OPT)
-
-sources=getopt.c
-ifeq ($(LIBCGETOPT),0)
-sources+=gnu/getopt.c gnu/getopt1.c
-endif
-
-objects=$(sources:.c=.o)
-
-binaries=getopt
-
-.PHONY: all clean realclean 
-all: $(binaries)
-
-clean:
-       -$(RM) $(objects) $(binaries) 
-
-%.o: %.c
-       $(CC) -c $(CPPFLAGS) $(CFLAGS) $*.c -o $*.o
-
-getopt: $(objects)
-       $(CC) $(LDFLAGS) -o $@ $(objects)
-
-install: getopt
-       $(INSTALL) -m 755 getopt $(bindir)
-       $(INSTALL) -m 644 getopt.1 $(man1dir)
-       $(INSTALL) -m 755 -d $(getoptdir)
-       $(INSTALL) -m 754 parse.bash parse.tcsh test.bash test.tcsh $(getoptdir)
diff --git a/lib/Makefile b/lib/Makefile
new file mode 100644 (file)
index 0000000..5503a60
--- /dev/null
@@ -0,0 +1,17 @@
+include ../MCONFIG
+
+CFLAGS=-I$(LIB) $(OPT)
+
+all: err.o my_reboot.o setproctitle.o
+
+err.o: err.c
+
+my_reboot.o: my_reboot.c linux_reboot.h
+
+setproctitle.o: setproctitle.h
+
+.PHONY: clean
+clean:
+       -rm -f *.o *~ core
+
+install:
similarity index 100%
rename from bsd/err.c
rename to lib/err.c
similarity index 100%
rename from bsd/err.h
rename to lib/err.h
diff --git a/lib/linux_reboot.h b/lib/linux_reboot.h
new file mode 100644 (file)
index 0000000..780d750
--- /dev/null
@@ -0,0 +1,30 @@
+extern int my_reboot(int);
+
+/*
+ * Magic values required to use _reboot() system call.
+ */
+
+#define        LINUX_REBOOT_MAGIC1     0xfee1dead
+#define        LINUX_REBOOT_MAGIC2     672274793
+#define        LINUX_REBOOT_MAGIC2A    85072278
+#define        LINUX_REBOOT_MAGIC2B    369367448
+
+
+/*
+ * Commands accepted by the _reboot() system call.
+ *
+ * RESTART     Restart system using default command and mode.
+ * HALT        Stop OS and give system control to ROM monitor, if any.
+ * CAD_ON      Ctrl-Alt-Del sequence causes RESTART command.
+ * CAD_OFF     Ctrl-Alt-Del sequence sends SIGINT to init task.
+ * POWER_OFF   Stop OS and remove all power from system, if possible.
+ * RESTART2    Restart system using given command string.
+ */
+
+#define        LINUX_REBOOT_CMD_RESTART        0x01234567
+#define        LINUX_REBOOT_CMD_HALT           0xCDEF0123
+#define        LINUX_REBOOT_CMD_CAD_ON         0x89ABCDEF
+#define        LINUX_REBOOT_CMD_CAD_OFF        0x00000000
+#define        LINUX_REBOOT_CMD_POWER_OFF      0x4321FEDC
+#define        LINUX_REBOOT_CMD_RESTART2       0xA1B2C3D4
+
diff --git a/lib/my_reboot.c b/lib/my_reboot.c
new file mode 100644 (file)
index 0000000..12ea4c9
--- /dev/null
@@ -0,0 +1,40 @@
+/* Including <unistd.h> makes sure that on a glibc system
+   <features.h> is included, which again defines __GLIBC__ */
+#include <unistd.h>
+#include "linux_reboot.h"
+
+#define USE_LIBC
+
+#ifdef USE_LIBC
+
+/* libc version */
+#if defined __GLIBC__ && __GLIBC__ >= 2
+#  include <sys/reboot.h>
+#  define REBOOT(cmd) reboot(cmd)
+#else
+extern int reboot(int, int, int);
+#  define REBOOT(cmd) reboot(LINUX_REBOOT_MAGIC1,LINUX_REBOOT_MAGIC2,(cmd))
+#endif
+int
+my_reboot(int cmd) {
+       return REBOOT(cmd);
+}
+
+#else /* no USE_LIBC */
+
+/* direct syscall version */
+#include <linux/unistd.h>
+
+#ifdef _syscall3
+_syscall3(int,  reboot,  int,  magic, int, magic_too, int, cmd);
+#else
+/* Let us hope we have a 3-argument reboot here */
+extern int reboot(int, int, int);
+#endif
+
+int
+my_reboot(int cmd) {
+       return reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, cmd);
+}
+
+#endif
similarity index 95%
rename from bsd/pathnames.h
rename to lib/pathnames.h
index f6e46721484cef55e3c559f577d4af26af7095a7..ab7b97dc8952daac084ea386f60725a443586122 100644 (file)
@@ -68,7 +68,8 @@
 #define _PATH_WTMP             LOGDIR "/wtmp"
 #define _PATH_WTMPLOCK         "/etc/wtmplock"
 
-#define        _PATH_DEFPATH           "/usr/local/bin:/bin:/usr/bin:."
+/* no more . in DEFPATH */
+#define        _PATH_DEFPATH           "/usr/local/bin:/bin:/usr/bin"
 #define        _PATH_DEFPATH_ROOT      SBINDIR ":/bin:" USRSBINDIR ":/usr/bin"
 #define        _PATH_HUSHLOGIN         ".hushlogin"
 #define        _PATH_LASTLOG           LOGDIR "/lastlog"
@@ -81,6 +82,8 @@
 #define _PATH_RC               "/etc/rc"
 #define _PATH_REBOOT           SBINDIR "/reboot"
 #define _PATH_SINGLE           "/etc/singleboot"
+#define _PATH_SHUTDOWN_CONF    "/etc/shutdown.conf"
+
 #define _PATH_SECURE           "/etc/securesingle"
 #define _PATH_USERTTY           "/etc/usertty"
 
diff --git a/lib/setproctitle.c b/lib/setproctitle.c
new file mode 100644 (file)
index 0000000..bff1362
--- /dev/null
@@ -0,0 +1,117 @@
+/* proctitle code - we know this to work only on linux... */
+
+/*
+**  SETPROCTITLE -- set process title for ps (from sendmail)
+**
+**      Parameters:
+**              fmt -- a printf style format string.
+**
+**      Returns:
+**              none.
+**
+**      Side Effects:
+**              Clobbers argv of our main procedure so ps(1) will
+**              display the title.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include "setproctitle.h"
+
+#ifndef SPT_PADCHAR
+#define SPT_PADCHAR     ' '
+#endif
+
+#ifndef SPT_BUFSIZE
+#define SPT_BUFSIZE     2048
+#endif
+
+extern char** environ;
+
+static char** argv0;
+static int argv_lth;
+
+void
+initproctitle (int argc, char **argv) {
+       int i;
+       char **envp = environ;
+
+       /*
+        * Move the environment so we can reuse the memory.
+        * (Code borrowed from sendmail.)
+        * WARNING: ugly assumptions on memory layout here;
+        *          if this ever causes problems, #undef DO_PS_FIDDLING
+        */
+       for (i = 0; envp[i] != NULL; i++)
+               continue;
+       environ = (char **) malloc(sizeof(char *) * (i + 1));
+       if (environ == NULL)
+               return;
+       for (i = 0; envp[i] != NULL; i++)
+               if ((environ[i] = strdup(envp[i])) == NULL)
+                       return;
+       environ[i] = NULL;
+
+       argv0 = argv;
+       if (i > 0)
+               argv_lth = envp[i-1] + strlen(envp[i-1]) - argv0[0];
+       else
+               argv_lth = argv0[argc-1] + strlen(argv0[argc-1]) - argv0[0];
+}      
+
+#if 0
+/* Nice code, but many places do not know about vsnprintf ... */
+void
+setproctitle (const char *fmt,...) {
+       char       *p;
+       int        i;
+       char       buf[SPT_BUFSIZE];
+       va_list    ap;
+
+       if (!argv0)
+               return;
+
+       va_start(ap, fmt);
+       (void) vsnprintf(buf, SPT_BUFSIZE, fmt, ap);
+       va_end(ap);
+
+       i = strlen (buf);
+       if (i > argv_lth - 2) {
+               i = argv_lth - 2;
+               buf[i] = '\0';
+       }
+       (void) strcpy (argv0[0], buf);
+       p = &argv0[0][i];
+       while (i < argv_lth)
+               *p++ = SPT_PADCHAR, i++;
+       argv0[1] = NULL;
+}
+#else
+void
+setproctitle (const char *prog, const char *txt) {
+        char       *p;
+        int        i;
+        char       buf[SPT_BUFSIZE];
+
+        if (!argv0)
+                return;
+
+       if (strlen(prog) + strlen(txt) + 5 > SPT_BUFSIZE)
+               return;
+
+        (void) sprintf(buf, "%s -- %s", prog, txt);
+
+        i = strlen (buf);
+        if (i > argv_lth - 2) {
+                i = argv_lth - 2;
+                buf[i] = '\0';
+        }
+        (void) strcpy (argv0[0], buf);
+        p = &argv0[0][i];
+        while (i < argv_lth)
+                *p++ = SPT_PADCHAR, i++;
+        argv0[1] = NULL;
+}
+#endif
diff --git a/lib/setproctitle.h b/lib/setproctitle.h
new file mode 100644 (file)
index 0000000..d57abda
--- /dev/null
@@ -0,0 +1,7 @@
+
+void initproctitle (int argc, char **argv);
+#if 0
+void setproctitle (const char *fmt, ...);
+#else
+void setproctitle (const char *prog, const char *txt);
+#endif
index 9f41fcd19346dfa4666a8e0fce396d219aa44143..f4bbc5a99e40643860c6906a747f0aa5bc540b4f 100644 (file)
@@ -82,54 +82,53 @@ all-misc: $(USRBIN.MISC)
 
 # Rules for everything else
 
-agetty.o: $(BSD)/pathnames.h
+agetty.o: $(LIB)/pathnames.h
 agetty: agetty.o
 chfn: chfn.o islocal.o setpwnam.o
-       $(CC) -o $@ $^ $(CRYPT) $(PAM)
+       $(CC) $(LDFLAGS) -o $@ $^ $(CRYPT) $(PAM)
 chsh: chsh.o islocal.o setpwnam.o
-       $(CC) -o $@ $^ $(CRYPT) $(PAM)
-islocal.o: $(BSD)/pathnames.h
-last.o: $(BSD)/pathnames.h
-last: last.o $(BSD)/getopt.o
+       $(CC) $(LDFLAGS) -o $@ $^ $(CRYPT) $(PAM)
+islocal.o: $(LIB)/pathnames.h
+last.o: $(LIB)/pathnames.h
+last: last.o
 
 ifeq "$(HAVE_PAM)" "yes"
-login: login.o 
-       $(CC) -o $@ $^ $(CRYPT) $(PAM)
+login: login.o $(LIB)/setproctitle.o
+       $(CC) $(LDFLAGS) -o $@ $^ $(CRYPT) $(PAM)
 else
-login: login.o checktty.o 
-       $(CC) -o $@ $^ $(CRYPT) 
+login: login.o $(LIB)/setproctitle.o checktty.o 
+       $(CC) $(LDFLAGS) -o $@ $^ $(CRYPT) 
 endif
 
-mesg: mesg.o $(BSD)/getopt.o $(BSD)/err.o
+mesg: mesg.o $(ERR_O)
 newgrp: newgrp.o 
-       $(CC) -o $@ $^ $(CRYPT) $(PAM)
-setpwnam.o: $(BSD)/pathnames.h
-shutdown.o: $(BSD)/pathnames.h
-shutdown: shutdown.o
-simpleinit.o: $(BSD)/pathnames.h
-simpleinit: simpleinit.o $(CRYPT)
-vipw.o: $(BSD)/pathnames.h
+       $(CC) $(LDFLAGS) -o $@ $^ $(CRYPT) $(PAM)
+setpwnam.o: $(LIB)/pathnames.h
+shutdown.o: $(LIB)/pathnames.h $(LIB)/linux_reboot.h
+shutdown: shutdown.o $(LIB)/my_reboot.o
+simpleinit.o: $(LIB)/pathnames.h $(LIB)/linux_reboot.h
+simpleinit: simpleinit.o $(LIB)/my_reboot.o
+vipw.o: $(LIB)/pathnames.h
 vipw: vipw.o
 
-newgrp.o: $(BSD)/pathnames.h
+newgrp.o: $(LIB)/pathnames.h
        $(CC) -c $(CFLAGS) $(PAMFL) newgrp.c 
 
 wall: wall.o ttymsg.o
 
 ifeq "$(USE_TTY_GROUP)" "yes"
-login.o: login.c $(BSD)/pathnames.h
+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 $(BSD)/err.h
+mesg.o: mesg.c $(LIB)/err.h
        $(CC) -c $(CFLAGS) -DUSE_TTY_GROUP mesg.c
 else
-login.o: $(BSD)/pathnames.h
+login.o: $(LIB)/pathnames.h
        $(CC) -c $(CFLAGS) $(PAMFL) login.c
-mesg.o: $(BSD)/err.h
+mesg.o: $(LIB)/err.h
 endif
 
-passwd: passwd.o islocal.o setpwnam.o $(CRYPT)
-passwd.o: passwd.c
-       $(CC) -c $(CFLAGS) passwd.c
+passwd: passwd.o islocal.o setpwnam.o
+       $(CC) $(LDFLAGS) -o $@ $^ $(CRYPT)
 
 ifeq "$(REQUIRE_PASSWORD)" "yes"
 CHSH_FLAGS:=$(CHSH_FLAGS) -DREQUIRE_PASSWORD
index 039589591be53d74f48a0ee00fee23fb1a06867d..96d7b38d035ebc1bce4941b3ee0930ad7fedabf3 100644 (file)
@@ -545,6 +545,9 @@ update_utmp(line)
     endutent();
 
     {
+#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1)
+       updwtmp(_PATH_WTMP, &ut);
+#else
        int lf;
 
        if ((lf = open(_PATH_WTMPLOCK, O_CREAT|O_WRONLY, 0660)) >= 0) {
@@ -556,8 +559,9 @@ update_utmp(line)
            flock(lf, LOCK_UN);
            close(lf);
        }
+#endif
     }
-#else
+#else /* not __linux__ */
     if ((ut_fd = open(UTMP_FILE, 2)) < 0) {
        error("%s: open for update: %m", UTMP_FILE);
     } else {
@@ -769,7 +773,7 @@ do_prompt(op, tp)
 #ifdef ISSUE
     FILE    *fd;
     int     oflag;
-    char    c;
+    int     c;
     struct utsname uts;
 
     (void) uname(&uts);
index f01d0ee82cba8af38b889d394a57f0aeea48b8c0..15873aa44e1c60c2ae271e9e68382cdcde52f8cb 100644 (file)
@@ -135,6 +135,8 @@ add_to_class(struct ttyclass *tc, char *tty)
 
 
 /* return true if tty is a pty. Very linux dependent */
+/* Note that the new dynamic ptys (say /dev/pty/0 etc) have major in 128-135 */
+/* We might try TIOCGPTN or so to recognise these new ones, if desired */
 static int
 isapty(const char *tty)
 {
@@ -146,20 +148,18 @@ isapty(const char *tty)
            return 0;
     sprintf(devname, "/dev/%s", tty);
 
-#if defined(__linux__) && defined(PTY_SLAVE_MAJOR)
-    /* this is for linux 1.3 and newer */
-    if((stat(devname, &stb) >= 0)
-       && major(stb.st_rdev) == PTY_SLAVE_MAJOR) {
-       return 1;
-    }
+#if defined(__linux__)
+    if((stat(devname, &stb) >= 0) && S_ISCHR(stb.st_mode)) {
+
+#if defined(PTY_SLAVE_MAJOR)
+           /* this is for linux 1.3 and newer */
+           if(major(stb.st_rdev) == PTY_SLAVE_MAJOR)
+                   return 1;
 #endif
 
-#if defined(__linux__)
-    /* this is for linux versions before 1.3, backward compat. */
-    if((stat(devname, &stb) >= 0)
-       && major(stb.st_rdev) == TTY_MAJOR
-       && minor(stb.st_rdev) >= 192) {
-       return 1;
+           /* this is for linux versions before 1.3, backward compat. */
+           if(major(stb.st_rdev) == TTY_MAJOR && minor(stb.st_rdev) >= 192)
+                   return 1;
     }
 #endif
     return 0;
index 8e962db0531611cd2823d3c24d6445f20f81efe5..3da2360f1de45487fb4610d3796783e1f766d499 100644 (file)
@@ -14,9 +14,6 @@
  * patches from Zefram <A.Main@dcs.warwick.ac.uk>
  *
  *  Hacked by Peter Breitenlohner, peb@mppmu.mpg.de,
- *    to allow peaceful coexistence with yp: using the changes by
- *     Alvaro Martinez Echevarria, alvaro@enano.etsit.upm.es, from
- *     passwd.c (now moved to setpwnam.c);
  *    to remove trailing empty fields.  Oct 5, 96.
  *
  */
@@ -32,6 +29,7 @@
 #include <errno.h>
 #include <ctype.h>
 #include <getopt.h>
+#include <locale.h>
 #include "my_crypt.h"
 #include "../version.h"
 
@@ -81,6 +79,9 @@ extern int setpwnam P((struct passwd *pwd));
 
 #define memzero(ptr, size) memset((char *) ptr, 0, size)
 
+/* we do not accept gecos field sizes lengther than MAX_FIELD_SIZE */
+#define MAX_FIELD_SIZE         256
+
 int main (argc, argv)
     int argc;
     char *argv[];
@@ -103,6 +104,9 @@ int main (argc, argv)
     for (cp = whoami; *cp; cp++)
        if (*cp == '/') whoami = cp + 1;
 
+    /* iscntrl() below should not reject actual names */
+    setlocale(LC_ALL,"");
+
     /*
      * "oldf" contains the users original finger information.
      * "newf" contains the changed finger information, and contains NULL
@@ -393,6 +397,13 @@ static int check_gecos_string (msg, gecos)
 {
     int i, c;
 
+    if (strlen(gecos) > MAX_FIELD_SIZE) {
+       if (msg != NULL)
+           printf("%s: ", msg);
+       printf("field is too long.\n");
+       return -1;
+    }
+
     for (i = 0; i < strlen (gecos); i++) {
        c = gecos[i];
        if (c == ',' || c == ':' || c == '=' || c == '"' || c == '\n') {
index 57ded290246156dd53922d07d068197c84ae7fee..42e87ca6036bede451aadc872f4481b4eab7eff6 100644 (file)
@@ -10,7 +10,7 @@
 .\"  $Revision: 1.1 $
 .\"  $Date: 1995/03/12 01:28:58 $
 .\"
-.TH CHSH 1 "October 13 1994" "chsh" "Linux Reference Manual"
+.TH CHSH 1 "7 October 1998" "chsh" "Linux Reference Manual"
 .SH NAME
 chsh \- change your login shell
 .SH SYNOPSIS
@@ -28,6 +28,8 @@ will accept the full pathname of any executable file on the system.
 However, it will issue a warning if the shell is not listed in the
 .I /etc/shells
 file.
+On the other hand, it can also be configured such that it will
+only accept shells listed in this file, unless you are root.
 .SH OPTIONS
 .TP
 .I "\-s, \-\-shell"
index f64cd0b782149c5b16fc8f650921e18326795fd5..8e8a51bc0e569e178f0ca886680e6081b6ddd24a 100644 (file)
  *   suggestion from Zefram.  Disallowing users with shells not in /etc/shells
  *   from changing their shell.
  *
- *  Hacked by Peter Breitenlohner, peb@mppmu.mpg.de,
- *    to allow peaceful coexistence with yp: using the changes by
- *     Alvaro Martinez Echevarria, alvaro@enano.etsit.upm.es, from
- *     passwd.c (now moved to setpwnam.c). Oct 5, 96.
- *
  */
 
 #if 0
diff --git a/login-utils/last.1.orig b/login-utils/last.1.orig
deleted file mode 100644 (file)
index 4d0deb8..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-.TH LAST 1 "20 March 1992"
-.SH NAME
-last \(em indicate last logins by user or terminal
-.SH SYNOPSIS
-.ad l
-.B last
-.RB [ \-\fP\fInumber\fP ]
-.RB [ \-f
-.IR filename ]
-.RB [ \-t
-.IR tty ]
-.RB [ \-h
-.IR hostname ]
-.RI [ name ...]
-.ad b
-.SH DESCRIPTION
-\fBLast\fP looks back in the \fBwtmp\fP file which records all logins
-and logouts for information about a user, a teletype or any group of
-users and teletypes.  Arguments specify names of users or teletypes of
-interest.  If multiple arguments are given, the information which
-applies to any of the arguments is printed.  For example ``\fBlast root
-console\fP'' would list all of root's sessions as well as all sessions
-on the console terminal.  \fBLast\fP displays the sessions of the
-specified users and teletypes, most recent first, indicating the times
-at which the session began, the duration of the session, and the
-teletype which the session took place on.  If the session is still
-continuing or was cut short by a reboot, \fBlast\fP so indicates.
-.LP
-The pseudo-user \fBreboot\fP logs in at reboots of the system.
-.LP
-\fBLast\fP with no arguments displays a record of all logins and
-logouts, in reverse order.
-.LP
-If \fBlast\fP is interrupted, it indicates how far the search has
-progressed in \fBwtmp\fP.  If interrupted with a quit signal \fBlast\fP
-indicates how far the search has progressed so far, and the search
-continues.
-.SH OPTIONS
-.IP \fB\-\fP\fInumber\fP
-limit the number of entries displayed to that specified by \fInumber\fP.
-.IP "\fB\-\fP \fIfilename\fP"
-Use \fIfilename\fP as the name of the accounting file instead of
-.BR /etc/wtmp .
-.IP "\fB\-t\fP \fItty\fP"
-List only logins on \fItty\fP.
-.IP "\fB\-h\fP \fIhostname\fP"
-List only logins from \fhostname\fP.
-.SH FILES
-/etc/wtmp \(em login data base
index 98ffef38fffcce6a4ad600fb9aee51a91d53a5b6..cf59b8ea6ed5babbda04a2ddf18ee5240112d20a 100644 (file)
@@ -45,6 +45,16 @@ static struct utmp   buf[1024];              /* utmp read buffer */
 #define        LMAX    (int)sizeof(buf[0].ut_line)     /* size of utmp tty field */
 #define        NMAX    (int)sizeof(buf[0].ut_name)     /* size of utmp name field */
 
+#ifndef MIN
+#define MIN(a,b)       (((a) < (b)) ? (a) : (b))
+#endif
+
+/* maximum sizes used for printing */
+/* probably we want a two-pass version that computes the right length */
+int hmax = MIN(HMAX, 16);
+int lmax = MIN(LMAX, 8);
+int nmax = MIN(NMAX, 16);
+
 typedef struct arg {
        char    *name;                          /* argument */
 #define        HOST_TYPE       -2
@@ -142,19 +152,19 @@ print_partial_line(bp)
     char *ct;
 
     ct = ctime(&bp->ut_time);
-    printf("%-*.*s  %-*.*s ", NMAX, NMAX, bp->ut_name, 
-          LMAX, LMAX, bp->ut_line);
+    printf("%-*.*s  %-*.*s ", nmax, nmax, bp->ut_name, 
+          lmax, lmax, bp->ut_line);
 
     if (dolong) {
        if (bp->ut_addr) {
            struct in_addr foo;
            foo.s_addr = bp->ut_addr;
-           printf("%-*.*s ", HMAX, HMAX, inet_ntoa(foo));
+           printf("%-*.*s ", hmax, hmax, inet_ntoa(foo));
        } else {
-           printf("%-*.*s ", HMAX, HMAX, "");
+           printf("%-*.*s ", hmax, hmax, "");
        }
     } else {
-       printf("%-*.*s ", HMAX, HMAX, bp->ut_host);
+       printf("%-*.*s ", hmax, hmax, bp->ut_host);
     }
 
     if (doyear) {
@@ -178,7 +188,7 @@ wtmp()
                lseek(), time();
        int     bytes, wfd;
        void    onintr();
-       char    *ct, *crmsg;
+       char    *ct, *crmsg = NULL;
 
        if ((wfd = open(file, O_RDONLY, 0)) < 0 || fstat(wfd, &stb) == -1) {
                perror(file);
@@ -191,7 +201,7 @@ wtmp()
        (void)signal(SIGQUIT, onintr);
 
        while (--bl >= 0) {
-           if (lseek(wfd, (long)(bl * sizeof(buf)), L_SET) == -1 ||
+           if (lseek(wfd, (long)(bl * sizeof(buf)), SEEK_SET) == -1 ||
                (bytes = read(wfd, (char *)buf, sizeof(buf))) == -1) {
                fprintf(stderr, "last: %s: ", file);
                perror((char *)NULL);
@@ -206,7 +216,7 @@ wtmp()
                    /* 
                     * utmp(5) also mentions that the user 
                     * name should be 'shutdown' or 'reboot'.
-                    * Not checking the name causes i.e. runlevel
+                    * Not checking the name causes e.g. runlevel
                     * changes to be displayed as 'crash'. -thaele
                     */
                    if (!strncmp(bp->ut_user, "reboot", NMAX) ||
diff --git a/login-utils/last.c.orig b/login-utils/last.c.orig
deleted file mode 100644 (file)
index 788aa66..0000000
+++ /dev/null
@@ -1,381 +0,0 @@
-/*
- * Copyright (c) 1987 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 MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifndef lint
-char copyright[] =
-"@(#) Copyright (c) 1987 Regents of the University of California.\n\
- All rights reserved.\n";
-#endif /* not lint */
-
-#ifndef lint
-static char sccsid[] = "@(#)last.c     5.11 (Berkeley) 6/29/88";
-#endif /* not lint */
-
-/*
- * last
- */
-#include <sys/param.h>
-#include <sys/stat.h>
-#include <sys/file.h>
-#include <signal.h>
-#include <string.h>
-#include <time.h>
-#include <utmp.h>
-#include <stdio.h>
-#include <getopt.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include "pathnames.h"
-
-#define        SECDAY  (24*60*60)                      /* seconds in a day */
-#define        NO      0                               /* false/no */
-#define        YES     1                               /* true/yes */
-
-static struct utmp     buf[1024];              /* utmp read buffer */
-
-#define        HMAX    (int)sizeof(buf[0].ut_host)     /* size of utmp host field */
-#define        LMAX    (int)sizeof(buf[0].ut_line)     /* size of utmp tty field */
-#define        NMAX    (int)sizeof(buf[0].ut_name)     /* size of utmp name field */
-
-typedef struct arg {
-       char    *name;                          /* argument */
-#define        HOST_TYPE       -2
-#define        TTY_TYPE        -3
-#define        USER_TYPE       -4
-       int     type;                           /* type of arg */
-       struct arg      *next;                  /* linked list pointer */
-} ARG;
-ARG    *arglist;                               /* head of linked list */
-
-typedef struct ttytab {
-       long    logout;                         /* log out time */
-       char    tty[LMAX + 1];                  /* terminal name */
-       struct ttytab   *next;                  /* linked list pointer */
-} TTY;
-TTY    *ttylist;                               /* head of linked list */
-
-static long    currentout,                     /* current logout value */
-               maxrec;                         /* records to display */
-static char    *file = _PATH_WTMP;             /* wtmp file */
-
-static void wtmp(), addarg(), hostconv();
-static int want();
-TTY *addtty();
-static char *ttyconv();
-
-int
-main(argc, argv)
-       int     argc;
-       char    **argv;
-{
-       extern int      optind;
-       extern char     *optarg;
-       int     ch;
-
-       while ((ch = getopt(argc, argv, "0123456789f:h:t:")) != EOF)
-               switch((char)ch) {
-               case '0': case '1': case '2': case '3': case '4':
-               case '5': case '6': case '7': case '8': case '9':
-                       /*
-                        * kludge: last was originally designed to take
-                        * a number after a dash.
-                        */
-                       if (!maxrec)
-                               maxrec = atol(argv[optind - 1] + 1);
-                       break;
-               case 'f':
-                       file = optarg;
-                       break;
-               case 'h':
-                       hostconv(optarg);
-                       addarg(HOST_TYPE, optarg);
-                       break;
-               case 't':
-                       addarg(TTY_TYPE, ttyconv(optarg));
-                       break;
-               case '?':
-               default:
-                       fputs("usage: last [-#] [-f file] [-t tty] [-h hostname] [user ...]\n", stderr);
-                       exit(1);
-               }
-       for (argv += optind; *argv; ++argv) {
-#define        COMPATIBILITY
-#ifdef COMPATIBILITY
-               /* code to allow "last p5" to work */
-               addarg(TTY_TYPE, ttyconv(*argv));
-#endif
-               addarg(USER_TYPE, *argv);
-       }
-       wtmp();
-       exit(0);
-}
-
-/*
- * wtmp --
- *     read through the wtmp file
- */
-static void
-wtmp()
-{
-       register struct utmp    *bp;            /* current structure */
-       register TTY    *T;                     /* tty list entry */
-       struct stat     stb;                    /* stat of file for size */
-       long    bl, delta,                      /* time difference */
-               lseek(), time();
-       int     bytes, wfd;
-       void    onintr();
-       char    *ct, *crmsg;
-
-       if ((wfd = open(file, O_RDONLY, 0)) < 0 || fstat(wfd, &stb) == -1) {
-               perror(file);
-               exit(1);
-       }
-       bl = (stb.st_size + sizeof(buf) - 1) / sizeof(buf);
-
-       (void)time(&buf[0].ut_time);
-       (void)signal(SIGINT, onintr);
-       (void)signal(SIGQUIT, onintr);
-
-       while (--bl >= 0) {
-               if (lseek(wfd, (long)(bl * sizeof(buf)), L_SET) == -1 ||
-                   (bytes = read(wfd, (char *)buf, sizeof(buf))) == -1) {
-                       fprintf(stderr, "last: %s: ", file);
-                       perror((char *)NULL);
-                       exit(1);
-               }
-               for (bp = &buf[bytes / sizeof(buf[0]) - 1]; bp >= buf; --bp) {
-                       /*
-                        * if the terminal line is '~', the machine stopped.
-                        * see utmp(5) for more info.
-                        */
-                       if (!strncmp(bp->ut_line, "~", LMAX)) {
-                               /* everybody just logged out */
-                               for (T = ttylist; T; T = T->next)
-                                       T->logout = -bp->ut_time;
-                               currentout = -bp->ut_time;
-                               crmsg = strncmp(bp->ut_name, "shutdown", NMAX) ? "crash" : "down ";
-                               if (!bp->ut_name[0])
-                                       (void)strcpy(bp->ut_name, "reboot");
-                               if (want(bp, NO)) {
-                                       ct = ctime(&bp->ut_time);
-                                       if(bp->ut_type != LOGIN_PROCESS)
-                                         printf("%-*.*s  %-*.*s %-*.*s %10.10s %5.5s \n", NMAX, NMAX, bp->ut_name, LMAX, LMAX, bp->ut_line, HMAX, HMAX, bp->ut_host, ct, ct + 11);
-                                       if (maxrec && !--maxrec)
-                                               return;
-                               }
-                               continue;
-                       }
-                       /* find associated tty */
-                       for (T = ttylist;; T = T->next) {
-                               if (!T) {
-                                       /* add new one */
-                                       T = addtty(bp->ut_line);
-                                       break;
-                               }
-                               if (!strncmp(T->tty, bp->ut_line, LMAX))
-                                       break;
-                       }
-                       if (bp->ut_name[0] && bp->ut_type != LOGIN_PROCESS
-                           && want(bp, YES)) {
-                               ct = ctime(&bp->ut_time);
-                               printf("%-*.*s  %-*.*s %-*.*s %10.10s %5.5s ", NMAX, NMAX, bp->ut_name, LMAX, LMAX, bp->ut_line, HMAX, HMAX, bp->ut_host, ct, ct + 11);
-                               if (!T->logout)
-                                       puts("  still logged in");
-                               else {
-                                       if (T->logout < 0) {
-                                               T->logout = -T->logout;
-                                               printf("- %s", crmsg);
-                                       }
-                                       else
-                                               printf("- %5.5s", ctime(&T->logout)+11);
-                                       delta = T->logout - bp->ut_time;
-                                       if (delta < SECDAY)
-                                               printf("  (%5.5s)\n", asctime(gmtime(&delta))+11);
-                                       else
-                                               printf(" (%ld+%5.5s)\n", delta / SECDAY, asctime(gmtime(&delta))+11);
-                               }
-                               if (maxrec != -1 && !--maxrec)
-                                       return;
-                       }
-                       T->logout = bp->ut_time;
-               }
-       }
-       ct = ctime(&buf[0].ut_time);
-       printf("\nwtmp begins %10.10s %5.5s \n", ct, ct + 11);
-}
-
-/*
- * want --
- *     see if want this entry
- */
-static int
-want(bp, check)
-       register struct utmp    *bp;
-       int     check;
-{
-       register ARG    *step;
-
-       if (check)
-               /*
-                * when uucp and ftp log in over a network, the entry in
-                * the utmp file is the name plus their process id.  See
-                * etc/ftpd.c and usr.bin/uucp/uucpd.c for more information.
-                */
-               if (!strncmp(bp->ut_line, "ftp", sizeof("ftp") - 1))
-                       bp->ut_line[3] = '\0';
-               else if (!strncmp(bp->ut_line, "uucp", sizeof("uucp") - 1))
-                       bp->ut_line[4] = '\0';
-       if (!arglist)
-               return(YES);
-
-       for (step = arglist; step; step = step->next)
-               switch(step->type) {
-               case HOST_TYPE:
-                       if (!strncmp(step->name, bp->ut_host, HMAX))
-                               return(YES);
-                       break;
-               case TTY_TYPE:
-                       if (!strncmp(step->name, bp->ut_line, LMAX))
-                               return(YES);
-                       break;
-               case USER_TYPE:
-                       if (!strncmp(step->name, bp->ut_name, NMAX))
-                               return(YES);
-                       break;
-       }
-       return(NO);
-}
-
-/*
- * addarg --
- *     add an entry to a linked list of arguments
- */
-static void
-addarg(type, arg)
-       int     type;
-       char    *arg;
-{
-       register ARG    *cur;
-
-       if (!(cur = (ARG *)malloc((unsigned int)sizeof(ARG)))) {
-               fputs("last: malloc failure.\n", stderr);
-               exit(1);
-       }
-       cur->next = arglist;
-       cur->type = type;
-       cur->name = arg;
-       arglist = cur;
-}
-
-/*
- * addtty --
- *     add an entry to a linked list of ttys
- */
-TTY *
-addtty(ttyname)
-       char    *ttyname;
-{
-       register TTY    *cur;
-
-       if (!(cur = (TTY *)malloc((unsigned int)sizeof(TTY)))) {
-               fputs("last: malloc failure.\n", stderr);
-               exit(1);
-       }
-       cur->next = ttylist;
-       cur->logout = currentout;
-       memcpy(cur->tty, ttyname, LMAX);
-       return(ttylist = cur);
-}
-
-/*
- * hostconv --
- *     convert the hostname to search pattern; if the supplied host name
- *     has a domain attached that is the same as the current domain, rip
- *     off the domain suffix since that's what login(1) does.
- */
-static void
-hostconv(arg)
-       char    *arg;
-{
-       static int      first = 1;
-       static char     *hostdot,
-                       name[MAXHOSTNAMELEN];
-       char    *argdot;
-
-       if (!(argdot = strchr(arg, '.')))
-               return;
-       if (first) {
-               first = 0;
-               if (gethostname(name, sizeof(name))) {
-                       perror("last: gethostname");
-                       exit(1);
-               }
-               hostdot = strchr(name, '.');
-       }
-       if (hostdot && !strcmp(hostdot, argdot))
-               *argdot = '\0';
-}
-
-/*
- * ttyconv --
- *     convert tty to correct name.
- */
-static char *
-ttyconv(arg)
-       char    *arg;
-{
-       char    *mval;
-
-       /*
-        * kludge -- we assume that all tty's end with
-        * a two character suffix.
-        */
-       if (strlen(arg) == 2) {
-               /* either 6 for "ttyxx" or 8 for "console" */
-               if (!(mval = malloc((unsigned int)8))) {
-                       fputs("last: malloc failure.\n", stderr);
-                       exit(1);
-               }
-               if (!strcmp(arg, "co"))
-                       (void)strcpy(mval, "console");
-               else {
-                       (void)strcpy(mval, "tty");
-                       (void)strcpy(mval + 3, arg);
-               }
-               return(mval);
-       }
-       if (!strncmp(arg, "/dev/", sizeof("/dev/") - 1))
-               return(arg + 5);
-       return(arg);
-}
-
-/*
- * onintr --
- *     on interrupt, we inform the user how far we've gotten
- */
-void
-onintr(signo)
-       int     signo;
-{
-       char    *ct;
-
-       ct = ctime(&buf[0].ut_time);
-       printf("\ninterrupted %10.10s %5.5s \n", ct, ct + 11);
-       if (signo == SIGINT)
-               exit(1);
-       (void)fflush(stdout);                   /* fix required for rsh */
-}
index 92a082c674ddedd9c4bcfc333519cbc215031197..a2acbd9f78a9e2bf2a5f80a15a8d52d5b8c0e731 100644 (file)
@@ -243,8 +243,7 @@ the user to for example run the command: xterm -e /bin/login.
 .PP
 .IP o
 A domain name suffix such as @.some.dom, meaning that the user may
-rlogin/telnet from any host whose domain name has the suffix
-.some.dom.
+rlogin/telnet from any host whose domain name has the suffix .some.dom.
 .PP
 .IP o
 A range of IPv4 addresses, written @x.x.x.x/y.y.y.y where x.x.x.x is
@@ -303,9 +302,6 @@ are allowed to log in from anywhere as is standard behavior.
 .BR shutdown (8)
 .SH BUGS
 
-Linux, unlike other draconian operating systems, does not check
-quotas.
-
 The undocumented BSD
 .B \-r
 option is not supported.  This may be required by some
index ebb0a22dab3a7cabaa6557ade36e8a964977dcdb..c742af75c1d1a6b8b9562f309bc22733b9d74610 100644 (file)
 
 #define SLEEP_EXIT_TIMEOUT 5
 
+#ifdef __linux__
+#define DO_PS_FIDDLING
+#endif
+
+#ifdef DO_PS_FIDDLING
+#include "setproctitle.h"
+#endif
+
 #if 0
 /* from before we had a lastlog.h file in linux */
 struct  lastlog
@@ -260,9 +268,7 @@ consoletty(int fd)
 
 
 int
-main(argc, argv)
-     int argc;
-     char **argv;
+main(int argc, char **argv)
 {
     extern int errno, optind;
     extern char *optarg, **environ;
@@ -270,8 +276,8 @@ main(argc, argv)
     register int ch;
     register char *p;
     int ask, fflag, hflag, pflag, cnt;
-    int quietlog, passwd_req, ioctlval;
-    char *domain, *salt, *ttyn, *pp;
+    int quietlog, passwd_req;
+    char *domain, *ttyn;
     char tbuf[MAXPATHLEN + 2], tname[sizeof(_PATH_TTY) + 10];
     char *ctime(), *ttyname(), *stypeof();
     time_t time();
@@ -286,7 +292,12 @@ main(argc, argv)
     pam_handle_t *pamh = NULL;
     struct pam_conv conv = { misc_conv, NULL };
     pid_t childPid;
-    int childStatus;
+    void (*oldSigHandler) ();
+#else
+    char *salt, *pp;
+#endif
+#ifndef __linux__
+    int ioctlval;
 #endif
 
     signal(SIGALRM, timedout);
@@ -298,6 +309,9 @@ main(argc, argv)
 #ifdef HAVE_QUOTA
     quota(Q_SETUID, 0, 0, 0);
 #endif
+#ifdef DO_PS_FIDDLING
+    initproctitle(argc, argv);
+#endif
     
     /*
      * -p is used by getty to tell login not to destroy the environment
@@ -313,6 +327,7 @@ main(argc, argv)
     username = tty = hostname = NULL;
     fflag = hflag = pflag = 0;
     passwd_req = 1;
+
     while ((ch = getopt(argc, argv, "fh:p")) != EOF)
       switch (ch) {
        case 'f':
@@ -353,8 +368,13 @@ main(argc, argv)
     argc -= optind;
     argv += optind;
     if (*argv) {
-       username = *argv;
+       char *p = *argv;
+       username = strdup(p);
        ask = 0;
+       /* wipe name - some people mistype their password here */
+       /* (of course we are too late, but perhaps this helps a little ..) */
+       while(*p)
+           *p++ = ' ';
     } else
       ask = 1;
     
@@ -377,7 +397,7 @@ main(argc, argv)
      */
     ioctlval = 0;
     ioctl(0, FIOSNBIO, &ioctlval);
-#endif
+#endif /* ! __linux__ */
     
     for (cnt = getdtablesize(); cnt > 2; cnt--)
       close(cnt);
@@ -472,7 +492,7 @@ main(argc, argv)
               (retcode == PAM_AUTHINFO_UNAVAIL))) {
            pam_get_item(pamh, PAM_USER, (const void **) &username);
            syslog(LOG_NOTICE,"FAILED LOGIN %d FROM %s FOR %s, %s",
-           failcount, hostname,username,pam_strerror(pamh, retcode));
+           failcount, hostname, username, pam_strerror(pamh, retcode));
            fprintf(stderr,"Login incorrect\n\n");
            pam_set_item(pamh,PAM_USER,NULL);
            retcode = pam_authenticate(pamh, 0);
@@ -520,8 +540,8 @@ main(argc, argv)
 #else /* ! USE_PAM */
 
     for (cnt = 0;; ask = 1) {
-       ioctlval = 0;
 #  ifndef __linux__
+       ioctlval = 0;
        ioctl(0, TIOCSETD, &ioctlval);
 #  endif
        
@@ -770,7 +790,7 @@ main(argc, argv)
        utmp.ut_line[sizeof(utmp.ut_line)-1] = 0;
        login(&utmp);
     }
-#else
+#else /* __linux__ defined */
     /* for linux, write entries in utmp and wtmp */
     {
        struct utmp ut;
@@ -781,8 +801,19 @@ main(argc, argv)
        
        utmpname(_PATH_UTMP);
        setutent();
-       while ((utp = getutent()) 
-              && !(utp->ut_pid == mypid)) /* nothing */;
+
+       /* Find mypid in utmp.
+login sometimes overwrites the runlevel entry in /var/run/utmp,
+confusing sysvinit. I added a test for the entry type, and the problem
+was gone. (In a runlevel entry, st_pid is not really a pid but some number
+calculated from the previous and current runlevel).
+Michael Riepe <michael@stud.uni-hannover.de>
+       */
+       while ((utp = getutent()))
+               if (utp->ut_pid == mypid
+                   && utp->ut_type >= INIT_PROCESS
+                   && utp->ut_type <= DEAD_PROCESS)
+                       break;
        
        if (utp) {
            memcpy(&ut, utp, sizeof(ut));
@@ -813,7 +844,20 @@ main(argc, argv)
        
        pututline(&ut);
        endutent();
-       
+
+#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1)
+       updwtmp(_PATH_WTMP, &ut);
+#else
+#if 0
+       /* The O_APPEND open() flag should be enough to guarantee
+          atomic writes at end of file. */
+       if((wtmp = open(_PATH_WTMP, O_APPEND|O_WRONLY)) >= 0) {
+               write(wtmp, (char *)&ut, sizeof(ut));
+               close(wtmp);
+       }
+#else
+       /* Probably all this locking below is just nonsense,
+          and the short version is OK as well. */
        { 
            int lf;
            if ((lf = open(_PATH_WTMPLOCK, O_CREAT|O_WRONLY, 0660)) >= 0) {
@@ -826,8 +870,10 @@ main(argc, argv)
                close(lf);
            }
        }
-    }
 #endif
+#endif /* __GLIBC__ */
+    }
+#endif /* __linux__ */
     
     dolastlog(quietlog);
     
@@ -903,7 +949,8 @@ main(argc, argv)
     setenv("TERM", termenv, 1);
     
     /* mailx will give a funny error msg if you forget this one */
-    { char tmp[MAXPATHLEN];
+    {
+      char tmp[MAXPATHLEN];
       /* avoid snprintf */
       if (sizeof(_PATH_MAILDIR) + strlen(pwd->pw_name) + 1 < MAXPATHLEN) {
              sprintf(tmp, "%s/%s", _PATH_MAILDIR, pwd->pw_name);
@@ -932,6 +979,10 @@ main(argc, argv)
        }
     }
 #endif
+
+#ifdef DO_PS_FIDDLING
+    setproctitle("login", username);
+#endif
     
     if (tty[sizeof("tty")-1] == 'S')
       syslog(LOG_INFO, "DIALUP AT %s BY %s", tty, pwd->pw_name);
@@ -956,41 +1007,53 @@ main(argc, argv)
     
     if (!quietlog) {
        struct stat st;
+       char *mail;
        
        motd();
-       /* avoid snprintf */
-       if (sizeof(_PATH_MAILDIR) + strlen(pwd->pw_name) + 1 < sizeof(tbuf)) {
-               sprintf(tbuf, "%s/%s", _PATH_MAILDIR, pwd->pw_name);
-               if (stat(tbuf, &st) == 0 && st.st_size != 0)
-                       printf("You have %smail.\n",
-                              (st.st_mtime > st.st_atime) ? "new " : "");
+       mail = getenv("MAIL");
+       if (mail && stat(mail, &st) == 0 && st.st_size != 0) {
+               printf("You have %smail.\n",
+                      (st.st_mtime > st.st_atime) ? "new " : "");
        }
     }
     
     signal(SIGALRM, SIG_DFL);
     signal(SIGQUIT, SIG_DFL);
-    signal(SIGINT, SIG_DFL);
     signal(SIGTSTP, SIG_IGN);
     signal(SIGHUP, SIG_DFL);
+
+#ifdef USE_PAM
+    /* We must fork before setuid() because we need to call
+     * pam_close_session() as root.
+     */
+    signal(SIGINT, SIG_IGN);
+    childPid = fork();
+    if (childPid < 0) {
+       /* error in fork() */
+       fprintf(stderr,"login: failure forking: %s", strerror(errno));
+       PAM_END;
+       exit(0);
+    } else if (childPid) {
+       /* parent - wait for child to finish, then cleanup session */
+       wait(NULL);
+       PAM_END;
+       exit(0);
+    }
+    /* child */
+#endif
+    signal(SIGINT, SIG_DFL);
     
     /* discard permissions last so can't get killed and drop core */
     if(setuid(pwd->pw_uid) < 0 && pwd->pw_uid) {
        syslog(LOG_ALERT, "setuid() failed");
-#ifdef USE_PAM
-       PAM_END;
-#endif
        exit(1);
     }
     
     /* wait until here to change directory! */
     if (chdir(pwd->pw_dir) < 0) {
        printf("No directory %s!\n", pwd->pw_dir);
-       if (chdir("/")) {
-#ifdef USE_PAM
-         PAM_END;
-#endif
+       if (chdir("/"))
          exit(0);
-       }
        pwd->pw_dir = "/";
        printf("Logging in with home = \"/\".\n");
     }
@@ -1023,15 +1086,6 @@ main(argc, argv)
 
     childArgv[childArgc++] = NULL;
 
-#ifdef USE_PAM 
-    /* There was some junk with fork()/exec()/signal()/wait() here
-       that was incorrect, and util-linux-2.7-11.src.rpm contains
-       a patch that makes the fork entirely useless.
-       If you introduce one again, please document in the source
-       what its purpose is. - aeb */
-    PAM_END;
-#endif /* USE_PAM */
-
     execvp(childArgv[0], childArgv + 1);
 
     if (!strcmp(childArgv[0], "/bin/sh")) 
@@ -1070,7 +1124,7 @@ getloginname()
                exit(0);
            }
        }
-       if (p > nbuf)
+       if (p > nbuf) {
          if (nbuf[0] == '-')
            fprintf(stderr,
                    "login names may not start with '-'.\n");
@@ -1079,6 +1133,7 @@ getloginname()
              username = nbuf;
              break;
          }
+       }
        
        cnt2++;
        if (cnt2 > 50) {
@@ -1190,7 +1245,7 @@ dolastlog(quiet)
     int fd;
     
     if ((fd = open(_PATH_LASTLOG, O_RDWR, 0)) >= 0) {
-       lseek(fd, (off_t)pwd->pw_uid * sizeof(ll), L_SET);
+       lseek(fd, (off_t)pwd->pw_uid * sizeof(ll), SEEK_SET);
        if (!quiet) {
            if (read(fd, (char *)&ll, sizeof(ll)) == sizeof(ll) &&
                ll.ll_time != 0) {
@@ -1204,7 +1259,7 @@ dolastlog(quiet)
                  printf("on %.*s\n",
                         (int)sizeof(ll.ll_line), ll.ll_line);
            }
-           lseek(fd, (off_t)pwd->pw_uid * sizeof(ll), L_SET);
+           lseek(fd, (off_t)pwd->pw_uid * sizeof(ll), SEEK_SET);
        }
        memset((char *)&ll, 0, sizeof(ll));
        time(&ll.ll_time);
index db44aa8e90bf56d3a830f1cde92e9d1e5c0b5501..b6a25a3f67f7dc55b1b3e9c297e0273441d3ee32 100644 (file)
@@ -34,10 +34,8 @@ reasons to choose a non-conformant password.
 
 The two argument form gives the 
 .IR user " the " password
-stated as the second argument. This may be useful when giving many
-users an initial generated password.  But it can also be extremely
-dangerous.  A simple script bug might change to root password to
-something unknown.
+stated as the second argument. Note that this password will
+be visible to people doing `ps' or so.  Avoid this form.
 
 Giving an empty string as the second argument erases the password for the
 user, but only in combination with the
@@ -111,6 +109,3 @@ Peter Orbaek (poe@daimi.aau.dk).
 .br
 Martin Schulze (joey@infodrom.north.de) with extensive rewriting and
 improving done.
-.br
-.SH MAINTAINER
-Nicolai Langfeldt (janl@math.uio.no)
index 4ed1b74d7c0104e6801cb272fc3804a928281533..0057a283b46c9534473c6d07479cc5de16c30d05 100644 (file)
@@ -3,17 +3,12 @@
  *
  * Initially written for Linux by Peter Orbaek <poe@daimi.aau.dk>
  * Currently maintained at ftp://ftp.daimi.aau.dk/pub/linux/poe/
-
- Hacked by Alvaro Martinez Echevarria, alvaro@enano.etsit.upm.es,
- to allow peaceful coexistence with yp. Nov 94.
-
- Hacked to allow root to set passwd from command line.
- by Arpad Magossanyi (mag@tas.vein.hu) 
-
- Hacked by Peter Breitenlohner, peb@mppmu.mpg.de,
- moved Alvaro's changes to setpwnam.c (so they get used
- by chsh and chfn as well). Oct 5, 96.
-
+ *
+ * Hacked by Alvaro Martinez Echevarria, alvaro@enano.etsit.upm.es,
+ * to allow peaceful coexistence with yp. Nov 94.
+ *
+ * Hacked to allow root to set passwd from command line.
+ * by Arpad Magossanyi (mag@tas.vein.hu)
  */
 
 /*
@@ -26,7 +21,7 @@
        or running a background job that just collects all command lines)
 
  *     work and second I wanted simplicity checks to be done for
- *     root, too. Only root can turn this of using the -f
+ *     root, too. Only root can turn this off using the -f
  *     switch. Okay, I started with this to support -V version
  *     information, but one thing comes to the next. *sigh*
  *     In a later step perhaps we'll be able to support shadow
index 443acc2af3782c648ef85eef89f0cd48730a8c60..961579bdcc9223f275305581be1e71a50a39e7c2 100644 (file)
@@ -1,6 +1,8 @@
 .\" Copyright 1992 Rickard E. Faith (faith@cs.unc.edu)
 .\" May be distributed under the GNU General Public License
-.TH SHUTDOWN 8 "20 November 1993" "Linux 1.2" "Linux Programmer's Manual"
+.\"
+.\" 
+.TH SHUTDOWN 8 "24 July 1998" "Linux 2.0" "Linux Programmer's Manual"
 .SH NAME
 shutdown \- close down the system
 .SH SYNOPSIS
@@ -98,7 +100,29 @@ detects (and deletes).
 .I /etc/singleboot
 .I /etc/nologin
 .I /var/log/wtmp
+.I /etc/shutdown.conf
 .fi
+.SH CONFIG
+The configuration file \fI/etc/shutdown.conf\fP is used to determine
+the action to take when halting the machine. The currently supported
+file format is extremely primitive. The first line must contain two
+strings separated by whitespace. The first string must be
+\fBHALT_ACTION\fP and the second specifies the action you wish to take
+on halt. The options allowed are:
+.TP
+.B halt
+This will simply halt the system. This is the default behaviour.
+Note also that this is the fallback if another option fails.
+.TP
+.B power_off
+This will use the kernel power shutdown facility. This is usually only
+available on machines with Advanced Power Management (APM).
+.TP
+.I programname
+This specifies a command to run to shut down the power. The first
+character must be a "/". Bear in mind that this command will be run
+with only the root filesystem mounted (and it will be read-only), and
+no daemons running.
 .SH "SEE ALSO"
 .BR umount (8),
 .BR login (1),
@@ -112,6 +136,6 @@ users are notified of shutdown only once or twice, instead of many times,
 and at shorter and shorter intervals as "apocalypse approaches."
 Some would construe this as a feature.
 .SH AUTHOR
-Peter Orbaek (poe@daimi.aau.dk)
-.br
-Modified by jrs@world.std.com
+This page documents the version of
+.B shutdown
+originally written by Peter Orbaek (poe@daimi.aau.dk).
index a63cbd6e9495306fec5810c36dda9f91bae938f1..8ba13b647cc8aa9afe1b05b08969485594bb9a8f 100644 (file)
@@ -1,6 +1,6 @@
 /* shutdown.c - shutdown a Linux system
  * Initially written by poe@daimi.aau.dk 
- * Currently maintained at ftp://ftp.daimi.aau.dk/pub/linux/poe/
+ * Currently maintained at ftp://ftp.daimi.aau.dk/pub/Software/Linux/
  */
 
 /*
@@ -24,6 +24,9 @@
  * Various changes and additions to resemble SunOS 4 shutdown/reboot/halt(8)
  * more closely by Scott Telford (s.telford@ed.ac.uk) 93/05/18.
  * (I butchered Scotts patches somewhat. - poe)
+ *
+ * Changes by Richard Gooch <rgooch@atnf.csiro.au> (butchered by aeb)
+ * introducing shutdown.conf.
  */
 
 #include <stdio.h>
@@ -35,6 +38,7 @@
 #include <string.h>
 #include <ctype.h>
 #include <signal.h>
+#include <errno.h>
 #include <sys/param.h>
 #include <termios.h>
 #include <mntent.h>
 #include <sys/wait.h>
 #include <syslog.h>
 #include <sys/resource.h>
+#include "linux_reboot.h"
 #include "pathnames.h"
 
-void usage(), int_handler(), write_user(struct utmp *);
-void wall(), write_wtmp(), unmount_disks(), unmount_disks_ourselves();
-void swap_off();
+static void usage(), int_handler(), write_user(struct utmp *);
+static void wall(), write_wtmp(), unmount_disks(), unmount_disks_ourselves();
+static void swap_off(), do_halt(char *);
 
 char   *prog;          /* name of the program */
 int    opt_reboot;     /* true if -r option or reboot command */
@@ -57,10 +62,15 @@ char        message[90];    /* reason for shutdown if any... */
 int    opt_single = 0; /* true is we want to boot singleuser */
 char   *whom;          /* who is shutting the system down */
 int    opt_msgset = 0; /* message set on command line */
+                       /* change 1 to 0 if no file is to be used by default */
+int    opt_use_config_file = 1;        /* read _PATH_SHUTDOWN_CONF */
+char   halt_action[256];               /* to find out what to do upon halt */
 
 /* #define DEBUGGING */
 
 #define WR(s) write(fd, s, strlen(s))
+#define ERRSTRING sys_errlist[errno]
+
 
 void
 usage()
@@ -70,19 +80,31 @@ usage()
        exit(1);
 }
 
+void
+my_puts(char *s)
+{
+       /* Use a fresh stdout after forking */
+       freopen(_PATH_CONSOLE, "w", stdout);
+       puts(s);
+       fflush(stdout);
+}
+
 void 
 int_handler()
 {
        unlink(_PATH_NOLOGIN);
        signal(SIGINT, SIG_DFL);
-       puts("Shutdown process aborted\n");
+       my_puts("Shutdown process aborted");
        exit(1);
 }
 
 int
-main(argc, argv)
-       int argc;
-       char *argv[];
+iswhitespace(int a) {
+       return (a == ' ' || a == '\t');
+}
+
+int
+main(int argc, char *argv[])
 {
        int c,i;        
        int fd;
@@ -90,7 +112,8 @@ main(argc, argv)
        
 #ifndef DEBUGGING
        if(geteuid()) {
-               fprintf(stderr, "%s: Only root can shut a system down.\n", argv[0]);
+               fprintf(stderr, "%s: Only root can shut a system down.\n",
+                       argv[0]);
                exit(1);
        }
 #endif
@@ -98,7 +121,10 @@ main(argc, argv)
        if(*argv[0] == '-') argv[0]++;  /* allow shutdown as login shell */
        prog = argv[0];
        if((ptr = strrchr(argv[0], '/'))) prog = ++ptr;
-       
+
+       /* All names (halt, reboot, fasthalt, fastboot, shutdown)
+          refer to the same program with the same options,
+          only the defaults differ. */
        if(!strcmp("halt", prog)) {
                opt_reboot = 0;
                opt_quiet = 1;
@@ -114,78 +140,105 @@ main(argc, argv)
                opt_quiet = 1;
                opt_fast = 0;
                timeout = 0;
-               if(argc > 1 && !strcmp(argv[1], "-s")) opt_single = 1;
        } else if(!strcmp("fastboot", prog)) {
                opt_reboot = 1;
                opt_quiet = 1;
                opt_fast = 1;
                timeout = 0;
-               if(argc > 1 && !strcmp(argv[1], "-s")) opt_single = 1;
        } else {
                /* defaults */
                opt_reboot = 0;
                opt_quiet = 0;
                opt_fast = 0;
                timeout = 2*60;
+       }
                
-               c = 0;
-               while(++c < argc) {
-                       if(argv[c][0] == '-') {
-                           for(i = 1; argv[c][i]; i++) {
+       c = 0;
+       while(++c < argc) {
+               if(argv[c][0] == '-') {
+                       for(i = 1; argv[c][i]; i++) {
                                switch(argv[c][i]) {
-                                 case 'h': 
-                                   opt_reboot = 0;
-                                   break;
-                                 case 'r':
-                                   opt_reboot = 1;
-                                   break;
-                                 case 'f':
-                                   opt_fast = 1;
-                                   break;
-                                 case 'q':
-                                   opt_quiet = 1;
-                                   break;
-                                 case 's':
-                                   opt_single = 1;
-                                   break;
+                               case 'C':
+                                       opt_use_config_file = 1;
+                                       break;
+                               case 'h': 
+                                       opt_reboot = 0;
+                                       break;
+                               case 'r':
+                                       opt_reboot = 1;
+                                       break;
+                               case 'f':
+                                       opt_fast = 1;
+                                       break;
+                               case 'q':
+                                       opt_quiet = 1;
+                                       break;
+                               case 's':
+                                       opt_single = 1;
+                                       break;
                                    
-                                 default:
-                                   usage();
+                               default:
+                                       usage();
                                }
-                           }
-                       } else if(!strcmp("now", argv[c])) {
-                               timeout = 0;
-                       } else if(argv[c][0] == '+') {
-                               timeout = 60 * atoi(&argv[c][1]);
-                       } else if (isdigit(argv[c][0])) {
-                               char *colon;
-                               int hour = 0;
-                               int minute = 0;
-                               time_t tics;
-                               struct tm *tt;
-                               int now, then;
+                       }
+               } else if(!strcmp("now", argv[c])) {
+                       timeout = 0;
+               } else if(argv[c][0] == '+') {
+                       timeout = 60 * atoi(&argv[c][1]);
+               } else if (isdigit(argv[c][0])) {
+                       char *colon;
+                       int hour = 0;
+                       int minute = 0;
+                       time_t tics;
+                       struct tm *tt;
+                       int now, then;
                                
-                               if((colon = strchr(argv[c], ':'))) {
-                                       *colon = '\0';
-                                       hour = atoi(argv[c]);
-                                       minute = atoi(++colon);
-                               } else usage();
+                       if((colon = strchr(argv[c], ':'))) {
+                               *colon = '\0';
+                               hour = atoi(argv[c]);
+                               minute = atoi(++colon);
+                       } else usage();
                                
-                               (void) time(&tics);
-                               tt = localtime(&tics);
+                       (void) time(&tics);
+                       tt = localtime(&tics);
                                
-                               now = 3600 * tt->tm_hour + 60 * tt->tm_min;
-                               then = 3600 * hour + 60 * minute;
-                               timeout = then - now;
-                               if(timeout < 0) {
-                                   fprintf(stderr, "That must be tomorrow, can't you wait till then?\n");
-                                   exit(1);
-                               }
-                       } else {
-                           strncpy(message, argv[c], sizeof(message));
-                           message[sizeof(message)-1] = '\0';
-                           opt_msgset = 1;
+                       now = 3600 * tt->tm_hour + 60 * tt->tm_min;
+                       then = 3600 * hour + 60 * minute;
+                       timeout = then - now;
+                       if(timeout < 0) {
+                               fprintf(stderr, "That must be tomorrow, "
+                                       "can't you wait till then?\n");
+                               exit(1);
+                       }
+               } else {
+                       strncpy(message, argv[c], sizeof(message));
+                       message[sizeof(message)-1] = '\0';
+                       opt_msgset = 1;
+               }
+       }
+
+       halt_action[0] = 0;
+
+       /* No doubt we shall want to extend this some day
+          and register a series of commands to be executed
+          at various points during the shutdown sequence,
+          and to define the number of milliseconds to sleep, etc. */
+       if (opt_use_config_file) {
+               char line[256], *p;
+               FILE *fp;
+
+               /*  Read and parse the config file */
+               halt_action[0] = '\0';
+               if ((fp = fopen (_PATH_SHUTDOWN_CONF, "r")) != NULL) {
+                       if (fgets (line, sizeof(line), fp) != NULL &&
+                           strncasecmp (line, "HALT_ACTION", 11) == 0 &&
+                           iswhitespace(line[11])) {
+                               p = line+11;
+                               while(iswhitespace(*p))
+                                       p++;
+                               strcpy(halt_action, p);
                        }
+                       fclose (fp);
                }
        }
 
@@ -212,6 +265,7 @@ main(argc, argv)
        
        /* so much for option-processing, now begin termination... */
        if(!(whom = getlogin())) whom = "ghost";
+       if(strlen(whom) > 40) whom[40] = 0; /* see write_user() */
 
        setpriority(PRIO_PROCESS, 0, PRIO_MIN);
        signal(SIGINT,  int_handler);
@@ -261,7 +315,8 @@ main(argc, argv)
        kill(1, SIGTSTP);       /* tell init not to spawn more getty's */
        write_wtmp();
        if(opt_single)
-               close(open(_PATH_SINGLE, O_CREAT|O_WRONLY, 0644));
+               if((fd = open(_PATH_SINGLE, O_CREAT|O_WRONLY, 0644)) >= 0)
+                       close(fd);
                
        sync();
 
@@ -272,7 +327,7 @@ main(argc, argv)
 #ifndef DEBUGGING
        /* a gentle kill of all other processes except init */
        kill(-1, SIGTERM);
-       sleep(2);
+       sleep(2);               /* default 2, some people need 5 */
 
        /* now use brute force... */
        kill(-1, SIGKILL);
@@ -292,14 +347,14 @@ main(argc, argv)
        sleep(1);
        
        if(opt_reboot) {
-               reboot(0xfee1dead, 672274793, 0x1234567);
+               my_reboot(LINUX_REBOOT_CMD_RESTART); /* RB_AUTOBOOT */
+               my_puts("\nWhy am I still alive after reboot?");
        } else {
-               freopen(_PATH_CONSOLE, "w", stdout);
-               printf("\nNow you can turn off the power...\n");
-               fflush(stdout);
+               my_puts("\nNow you can turn off the power...");
+
                /* allow C-A-D now, faith@cs.unc.edu, re-fixed 8-Jul-96 */
-               reboot(0xfee1dead, 672274793, 0x89abcdef);
-               reboot(0xfee1dead, 672274793, 0xcdef0123);
+               my_reboot(LINUX_REBOOT_CMD_CAD_ON); /* RB_ENABLE_CAD */
+               do_halt(halt_action);
        }
        /* NOTREACHED */
        exit(0); /* to quiet gcc */
@@ -307,6 +362,31 @@ main(argc, argv)
 
 /*** end of main() ***/
 
+void
+do_halt(char *action) {
+       if (strcasecmp (action, "power_off") == 0) {
+               printf("Calling kernel power-off facility...\n");
+               fflush(stdout);
+               my_reboot(LINUX_REBOOT_CMD_POWER_OFF);
+               printf("Error powering off\t%s\n", ERRSTRING);
+               fflush(stdout);
+               sleep (2);
+       } else
+
+       /* This should be improved; e.g. Mike Jagdis wants "/sbin/mdstop -a" */
+       /* Maybe we should also fork and wait */
+       if (action[0] == '/') {
+               printf("Executing the program \"%s\" ...\n", action);
+               fflush(stdout);
+               execl(action, action, NULL);
+               printf("Error executing\t%s\n", ERRSTRING);
+               fflush(stdout);
+               sleep (2);
+       }
+
+       my_reboot(LINUX_REBOOT_CMD_HALT); /* RB_HALT_SYSTEM */
+}
+
 void
 write_user(struct utmp *ut)
 {
@@ -319,7 +399,7 @@ write_user(struct utmp *ut)
        (void) strncat(term, ut->ut_line, sizeof(ut->ut_line));
 
        /* try not to get stuck on a mangled ut_line entry... */
-       if((fd = open(term, O_RDWR|O_NONBLOCK)) < 0)
+       if((fd = open(term, O_WRONLY|O_NONBLOCK)) < 0)
                return;
 
        sprintf(msg, "\007\r\nURGENT: broadcast message from %s:\r\n", whom);
@@ -393,7 +473,7 @@ swap_off()
 
        sync();
        if ((pid = fork()) < 0) {
-               printf("Cannot fork for swapoff. Shrug!\n");
+               my_puts("Cannot fork for swapoff. Shrug!");
                return;
        }
        if (!pid) {
@@ -401,7 +481,8 @@ swap_off()
                execl("/etc/swapoff", SWAPOFF_ARGS, NULL);
                execl("/bin/swapoff", SWAPOFF_ARGS, NULL);
                execlp("swapoff", SWAPOFF_ARGS, NULL);
-               puts("Cannot exec swapoff, hoping umount will do the trick.");
+               my_puts("Cannot exec swapoff, "
+                         "hoping umount will do the trick.");
                exit(0);
        }
        while ((result = wait(&status)) != -1 && result != pid)
@@ -419,20 +500,20 @@ unmount_disks()
 
        sync();
        if ((pid = fork()) < 0) {
-               printf("Cannot fork for umount, trying manually.\n");
+               my_puts("Cannot fork for umount, trying manually.");
                unmount_disks_ourselves();
                return;
        }
        if (!pid) {
                execl(_PATH_UMOUNT, UMOUNT_ARGS, NULL);
-               printf("Cannot exec %s, trying umount.\n", _PATH_UMOUNT);
+               my_puts("Cannot exec " _PATH_UMOUNT ", trying umount.");
                execlp("umount", UMOUNT_ARGS, NULL);
-               puts("Cannot exec umount, giving up on umount.");
+               my_puts("Cannot exec umount, giving up on umount.");
                exit(0);
        }
        while ((result = wait(&status)) != -1 && result != pid)
                ;
-       puts("Unmounting any remaining filesystems...");
+       my_puts("Unmounting any remaining filesystems...");
        unmount_disks_ourselves();
 }
 
@@ -450,7 +531,7 @@ unmount_disks_ourselves()
        
        sync();
        if (!(mtab = setmntent(_PATH_MTAB, "r"))) {
-               printf("shutdown: Cannot open %s.\n", _PATH_MTAB);
+               my_puts("shutdown: Cannot open " _PATH_MTAB ".");
                return;
        }
        n = 0;
index 14d8cfad280bbc95e7f2770aa93876c424e0325b..1664404c353571ac279bc0ced96b15c628105dfd 100644 (file)
 #include <sys/sysmacros.h>
 #include <utmp.h>
 #ifdef SHADOW_PWD
-#include <shadow.h>
+#  include <shadow.h>
 #endif
-
+#include "my_crypt.h"
 #include "pathnames.h"
+#include "linux_reboot.h"
 
 #define CMDSIZ 150     /* max size of a line in inittab */
 #define NUMCMD 30      /* max number of lines in inittab */
@@ -411,13 +412,14 @@ void int_handler()
        
        sync();
        sync();
-       if((pid = fork()) == 0) {
-               /* reboot properly... */
+       pid = fork();
+       if (pid > 0)
+               return;
+       if (pid == 0)   /* reboot properly... */
                execl(_PATH_REBOOT, _PATH_REBOOT, (char *)0);
-               reboot(0xfee1dead, 672274793, 0x1234567);
-       } else if(pid < 0)
-               /* fork failed, try the hard way... */
-               reboot(0xfee1dead, 672274793, 0x1234567);
+
+       /* fork or exec failed, try the hard way... */
+       my_reboot(LINUX_REBOOT_CMD_RESTART);
 }
 
 void set_tz()
index a5763b105e0a372008920b8ac9019971f1db044a..50270a6e3807b6d405ab096a328c042c2648eda9 100644 (file)
@@ -190,15 +190,14 @@ pw_unlock()
 
 
 void
-pw_edit(notsetuid)
-       int notsetuid;
+pw_edit(int notsetuid)
 {
        int pstat;
        pid_t pid;
        char *p, *editor;
 
        if (!(editor = getenv("EDITOR")))
-               editor = _PATH_VI;
+               editor = strdup(_PATH_VI); /* adia@egnatia.ee.auth.gr */
        if ((p = strrchr(strtok(editor," \t"), '/')) != NULL)
                ++p;
        else 
index e33165f7fa7f4d57343532f475bd7c70f4465757..9ccf489b17de1e50037c21074c7673bd29a135f4 100644 (file)
@@ -31,9 +31,10 @@ USRBIN:=$(USRBIN) reset
 MAN1:=$(MAN1) reset.1
 endif
 
-# ifeq "$(HAVE_SYSVINIT)" "no"
-# USRBIN:=$(USRBIN) pidof
-# endif
+# For script only
+ifeq "$(HAVE_OPENPTY)" "yes"
+CFLAGS:=$(CFLAGS) -DHAVE_OPENPTY
+endif
 
 # Programs requiring special compilation
 
@@ -58,16 +59,16 @@ endif
 
 # Rules for everything else
 
-cal: cal.o $(BSD)/getopt.o $(BSD)/err.o
+cal: cal.o $(ERR_O)
 chkdupexe: chkdupexe.pl
 clear: clear.sh
 kill: kill.o procs.o
-logger: logger.o $(BSD)/getopt.o
+logger: logger.o
 mcookie: mcookie.o md5.o
 mcookie.o: mcookie.c md5.h
 md5.o: md5.c md5.h
 reset: reset.sh
-# pidof: pidof.o procs.o
+
 ifeq "$(HAVE_NCURSES)" "yes"
 setterm: setterm.o
 endif
index 80d95b27d88407cbf7418075460a21e780a5ce19..9d41dc5edcd07f8abc1235ea4df0417c8a1e1296 100644 (file)
@@ -42,7 +42,7 @@
 .Nd displays a calendar
 .Sh SYNOPSIS
 .Nm cal
-.Op Fl jy
+.Op Fl mjy
 .Op Ar month Op Ar year
 .Sh DESCRIPTION
 .Nm Cal
@@ -51,6 +51,8 @@ If arguments are not specified,
 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.
 .It Fl j
 Display julian dates (days one-based, numbered from January 1).
 .It Fl y
index 9d44d327b2edd2e07c64f2ac96a1df57aff5b842..ab642014097b44bd1bc9b2ee88734fd34465fd2e 100644 (file)
  * SUCH DAMAGE.
  */
 
+/* 1999-02-01  Jean-Francois Bignolles: added option '-m' to display
+ *             monday as the first day of the week.
+ */
+
 /* This defines _LINUX_C_LIB_VERSION_MAJOR, dunno about gnulibc.  We
    don't want it to read /usr/i586-unknown-linux/include/_G_config.h
    so we specify fill path.  Were we got /usr/i586-unknown-linux from?
@@ -72,7 +76,7 @@
 #define        FIRST_MISSING_DAY       639787          /* 3 Sep 1752 */
 #define        NUMBER_MISSING_DAYS     11              /* 11 day correction */
 
-#define        MAXDAYS                 42              /* max slots in a month array */
+#define        MAXDAYS                 43              /* max slots in a month array */
 #define        SPACE                   -1              /* used in day array */
 
 static int days_in_month[2][13] = {
@@ -87,6 +91,7 @@ int sep1752[MAXDAYS] = {
        SPACE,  SPACE,  SPACE,  SPACE,  SPACE,  SPACE,  SPACE,
        SPACE,  SPACE,  SPACE,  SPACE,  SPACE,  SPACE,  SPACE,
        SPACE,  SPACE,  SPACE,  SPACE,  SPACE,  SPACE,  SPACE,
+       SPACE
 }, j_sep1752[MAXDAYS] = {
        SPACE,  SPACE,  245,    246,    258,    259,    260,
        261,    262,    263,    264,    265,    266,    267,
@@ -94,6 +99,7 @@ int sep1752[MAXDAYS] = {
        SPACE,  SPACE,  SPACE,  SPACE,  SPACE,  SPACE,  SPACE,
        SPACE,  SPACE,  SPACE,  SPACE,  SPACE,  SPACE,  SPACE,
        SPACE,  SPACE,  SPACE,  SPACE,  SPACE,  SPACE,  SPACE,
+       SPACE
 }, empty[MAXDAYS] = {
        SPACE,  SPACE,  SPACE,  SPACE,  SPACE,  SPACE,  SPACE,
        SPACE,  SPACE,  SPACE,  SPACE,  SPACE,  SPACE,  SPACE,
@@ -101,10 +107,13 @@ int sep1752[MAXDAYS] = {
        SPACE,  SPACE,  SPACE,  SPACE,  SPACE,  SPACE,  SPACE,
        SPACE,  SPACE,  SPACE,  SPACE,  SPACE,  SPACE,  SPACE,
        SPACE,  SPACE,  SPACE,  SPACE,  SPACE,  SPACE,  SPACE,
+       SPACE
 };
 
 char day_headings[]   = " S  M Tu  W Th  F  S ";
+/* week1stday = 1  =>   " M Tu  W Th  F  S  S " */
 char j_day_headings[] = "  S   M  Tu   W  Th   F   S ";
+/* week1stday = 1  =>   "  M  Tu   W  Th   F   S   S " */
 const char *full_month[12];
 
 /* leap year -- account for gregorian reformation in 1752 */
@@ -124,6 +133,8 @@ const char *full_month[12];
 #define        leap_years_since_year_1(yr) \
        ((yr) / 4 - centuries_since_1700(yr) + quad_centuries_since_1700(yr))
 
+/* 0 => sunday (default), 1 => monday */
+int week1stday;
 int julian;
 
 void   ascii_day __P((char *, int));
@@ -153,10 +164,12 @@ main(argc, argv)
 #endif
 
        setlocale(LC_ALL,"");
-       headers_init();
        yflag = 0;
-       while ((ch = getopt(argc, argv, "jy")) != EOF)
+       while ((ch = getopt(argc, argv, "mjy")) != EOF)
                switch(ch) {
+               case 'm':
+                       week1stday = 1;
+                       break;
                case 'j':
                        julian = 1;
                        break;
@@ -190,6 +203,7 @@ main(argc, argv)
        default:
                usage();
        }
+       headers_init();
 
        if (month)
                monthly(month, year);
@@ -209,22 +223,28 @@ main(argc, argv)
 
 void headers_init(void)
 {
-  int i;
+  int i, wd;
 
   strcpy(day_headings,"");
   strcpy(j_day_headings,"");
-  
-  for(i = 0 ; i < 7 ; i++ ) {
+
 #if defined(__linux__) && (_LINUX_C_LIB_VERSION_MAJOR > 4 || __GNU_LIBRARY__ > 1)
-     strncat(day_headings,nl_langinfo(ABDAY_1+i),2);
-     strcat(j_day_headings,nl_langinfo(ABDAY_1+i));
+# define weekday(wd)   nl_langinfo(ABDAY_1+wd)
 #else
-     strncat(day_headings,_time_info->abbrev_wkday[i],2);
-     strcat(j_day_headings,_time_info->abbrev_wkday[i]);
+# define weekday(wd)   _time_info->abbrev_wkday[wd]
 #endif
+  
+  for(i = 0 ; i < 7 ; i++ ) {
+     wd = (i + week1stday) % 7;
+     strncat(day_headings,weekday(wd),2);
+     strcat(j_day_headings,weekday(wd));
+     if (strlen(weekday(wd)) == 2)
+       strcat(j_day_headings," ");
      strcat(day_headings," ");
      strcat(j_day_headings," ");
   }
+
+#undef weekday
   
   for (i = 0; i < 12; i++) {
 #if defined(__linux__) && (_LINUX_C_LIB_VERSION_MAJOR > 4 || __GNU_LIBRARY__ > 1)
@@ -341,15 +361,16 @@ day_array(month, year, days)
        int *days;
 {
        int day, dw, dm;
+       int *d_sep1752;
 
        if (month == 9 && year == 1752) {
-               memmove(days,
-                       julian ? j_sep1752 : sep1752, MAXDAYS * sizeof(int));
+               d_sep1752 = julian ? j_sep1752 : sep1752;
+               memcpy(days, d_sep1752 + week1stday, MAXDAYS * sizeof(int));
                return;
        }
-       memmove(days, empty, MAXDAYS * sizeof(int));
+       memcpy(days, empty, MAXDAYS * sizeof(int));
        dm = days_in_month[leap_year(year)][month];
-       dw = day_in_week(1, month, year);
+       dw = (day_in_week(1, month, year) - week1stday + 7) % 7;
        day = julian ? day_in_year(1, month, year) : 1;
        while (dm--)
                days[dw++] = day++;
@@ -466,6 +487,6 @@ void
 usage()
 {
 
-       (void)fprintf(stderr, "usage: cal [-jy] [[month] year]\n");
+       (void)fprintf(stderr, "usage: cal [-mjy] [[month] year]\n");
        exit(1);
 }
old mode 100644 (file)
new mode 100755 (executable)
index f6111de..82ee9e9
@@ -1,4 +1,4 @@
-#!/usr/bin/perl5 -w
+#!/usr/bin/perl -w
 #
 # chkdupexe version 2.1.1
 #
@@ -27,7 +27,7 @@
 $execdirs='/bin /sbin /usr/bin /usr/sbin /usr/local/bin /usr/local/sbin '.
   '/usr/X11/bin /usr/bin/X11 /usr/local/X11/bin '.
   '/usr/TeX/bin /usr/tex/bin /usr/games '.
-  '/usr/local/games /usr/intervies/bin/LINUX';
+  '/usr/local/games';
 
 # Values from /usr/include/linux/errno.h.  Existence of linux/errno.ph is not
 # something to count on... :-(
@@ -96,6 +96,8 @@ while (($prog,$paths)=each %progs) {
 }
 close(LS);
 
+exit 0;
+
 @unchecked=();
 # Check if the users PATH contains something I've not checked. The site admin
 # might want to know about inconsistencies in user PATHs and chkdupexec 
@@ -108,6 +110,6 @@ foreach $dir (split(/:/,$ENV{'PATH'})) {
   $didthis{$device,$inode}=1;
 }
 
-print "Warning: Your path contanis these directories which chkdupexe have not checked:\n",join(',',@unchecked),
+print "Warning: Your path contains these directories which chkdupexe has not checked:\n",join(',',@unchecked),
   ".\nPlease review the execdirs list in chkdupexe.\n"
     if ($#unchecked>=$[);
index 1ccc201f6702c077fa308138d58520b47c83f4b7..7d17c82484ed2706afd3d6e2e730d93c05a09cfa 100644 (file)
@@ -43,8 +43,8 @@ Newline
 .IP %t 
 Tab
 .IP %X
-Number of days remaining until X-Day. (Not valid if the SubGenius options are not
-compiled in.)
+Number of days remaining until X-Day. (Not valid if the SubGenius options
+are not compiled in.)
 .IP %{
 .IP %}
 Used to enclose the part of the string which is to be replaced with the
@@ -80,6 +80,12 @@ will produce undefined behaviour if asked to produce the date for St. Tib's
 day and its format string does not contain the St. Tib's Day delimiters 
 %{ and %}.
 
+.SH NOTE
+
+After `X-Day' passed without incident, the Church of the SubGenius
+declared that it had got the year upside down - X-Day is actually in 8661 AD
+rather than 1998 AD.  Thus, the True X-Day is Cfn 40, 9827.
+
 .SH AUTHOR
 .nh
 Original program by Druel the Chaotic aka Jeremy Johnson (mpython@gnu.ai.mit.edu)
@@ -96,6 +102,8 @@ Public domain. All rites reversed.
 
 date(1),
 .br
+http://www.subgenius.com/
+.br
 Malaclypse the Younger, 
 .I "Principia Discordia, Or How I Found Goddess And What I Did To Her When I Found Her"
 
index f838d1c63fe4e1a76dde8aaa61b2b58d66ae5405..09704e0b47eed92b7f074b141cebd0dda1f981b5 100644 (file)
@@ -307,12 +307,20 @@ struct disc_time convert(int nday, int nyear)
 
 #ifdef KILL_BOB
 
-/* Code for counting down to X-Day, X-Day being Cfn 40, 3164 */
+/* Code for counting down to X-Day, X-Day being Cfn 40, 3164 
+ *
+ * After `X-Day' passed without incident, the CoSG declared that it had 
+ * got the year upside down --- X-Day is actually in 8661 AD rather than 
+ * 1998 AD.
+ *
+ * Thus, the True X-Day is Cfn 40, 9827.
+ *
+ */
 
 int xday_countdown(int yday, int year) {
     int r=(185-yday)+(((yday<59)&&(leapp(year)))?1:0);
-    while(year<3164) r+=(leapp(++year)?366:365);
-    while(year>3164) r-=(leapp(year--)?366:365);
+    while(year<9827) r+=(leapp(++year)?366:365);
+    while(year>9827) r-=(leapp(year--)?366:365);
     return r;
 }
 
diff --git a/misc-utils/hostname.c.orig b/misc-utils/hostname.c.orig
deleted file mode 100644 (file)
index b7e61d1..0000000
+++ /dev/null
@@ -1,187 +0,0 @@
-/* hostname -- set the host name or show the host/domain name
-
-   Copyright (C) 1994 Peter Tobias
-
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2, or (at your option)
-   any later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-*/
-
-
-#include <stdio.h>
-#include <unistd.h>
-#include <getopt.h>
-#include <string.h>
-#include <netdb.h>
-#include <errno.h>
-#include <sys/param.h>
-
-#define NO_OPT -1
-
-static char *program_name;
-static const char *version_string = "hostname 1.5";
-
-static void sethname(char *);
-static void showhname(char *, int);
-static void usage(void);
-
-static void sethname(char *hname)
-{
-       if(sethostname(hname, strlen(hname))) {
-               switch(errno) {
-                       case EPERM:
-                               fprintf(stderr,"%s: you must be root to change the host name\n", program_name);
-                               break;
-                       case EINVAL:
-                               fprintf(stderr,"%s: name too long\n", program_name);
-                               break;
-                       default:
-               }
-               exit(1);
-       };
-}
-
-static void showhname(char *hname, int c)
-{
-       struct hostent *hp;
-       register char *p;
-
-       if (!(hp = gethostbyname(hname))) {
-               herror(program_name);
-               exit(1);
-       }
-
-       if (!(p = strchr(hp->h_name, '.'))) {
-               fprintf(stderr,"%s: can't find a FQDN for the host name `%s'\n", program_name, hname);
-               exit(1);
-       }
-
-       switch(c) {
-               case 'd':
-                       printf("%s\n", ++p);
-                       break;
-               case 'f':
-                       printf("%s\n", hp->h_name);
-                       break;
-               case 's':
-                       *p = '\0';
-                       printf("%s\n", hp->h_name);
-                       break;
-               default:
-       }
-}
-
-static void usage(void)
-{
-  printf("Usage: %s [OPTION]... [hostname]\n\n\
-  -d, --domain                 display the DNS domain name\n\
-  -F, --file filename          read the host name from file\n\
-  -f, --fqdn, --long           display the long host name (FQDN)\n\
-  -s, --short                  display the short host name\n\
-  -h, --help                   display this help and exit\n\
-  -v, --version                output version information and exit\n\
-\n\
-   When the program is called without any arguments, it displays the\n\
-   current host name as set by the hostname command. If an argument\n\
-   is given, the program will set the value of the host name to the\n\
-   value specified.\n\
-   Unless you are using bind or NIS for host lookups you can change the\n\
-   FQDN (Fully Qualified Domain Name) and the DNS domain name (which is\n\
-   part of the FQDN) in the /etc/hosts file.\n", program_name);
-}
-
-int main(int argc, char **argv)
-{
-       int c;
-       int option_index = 0;
-
-       char myname[MAXHOSTNAMELEN+1];
-
-       static const struct option long_options[] =
-       {
-               {"domain", no_argument, 0, 'd'},
-               {"file", required_argument, 0, 'F'},
-               {"fqdn", no_argument, 0, 'f'},
-               {"help", no_argument, 0, 'h'},
-               {"long", no_argument, 0, 'f'},
-               {"short", no_argument, 0, 's'},
-               {"version", no_argument, 0, 'v'},
-               {0, 0, 0, 0}
-       };
-
-       program_name = (rindex(argv[0], '/')) ? rindex(argv[0], '/') + 1 : argv[0];
-
-       if (strcmp(program_name, "dnsdomainname") == 0) {
-               if (argc > 1) {
-                       fprintf(stderr,"%s: You can't change the DNS domainname with this command\n", program_name);
-                       fprintf(stderr,"\nUnless you are using bind or NIS for host lookups you can change the DNS\n");
-                       fprintf(stderr,"domain name (which is part of the FQDN) in the /etc/hosts file.\n");
-                       exit(1);
-               }
-               c = 'd';
-       } else
-               c = getopt_long(argc, argv, "dfF:hsv", long_options, &option_index);
-
-       gethostname(myname, sizeof(myname));
-
-       switch(c)
-       {
-               case 'd':
-               case 'f':
-               case 's':
-                       showhname(myname, c);
-                       break;
-               case 'F':
-                       {
-                       register FILE *fd;
-                       register char *p;
-                       char fline[MAXHOSTNAMELEN];
-
-                       if ((fd = fopen(optarg, "r")) != NULL) {
-                               while (fgets(fline, sizeof(fline), fd) != NULL)
-                                       if ((p = index(fline, '\n')) != NULL) {
-                                               *p = '\0';
-                                               if (fline[0] == '#')
-                                                       continue;
-                                               sethname(fline);
-                                       }
-                               (void) fclose(fd);
-                       } else {
-                               fprintf(stderr,"%s: can't open `%s'\n",
-                                   program_name, optarg);
-                               exit(1);
-                       }
-                       }
-                       break;
-               case 'h':
-                       usage();
-                       break;
-               case 'v':
-                       printf("%s\n", version_string);
-                       break;
-               case '?':
-                       fprintf(stderr,"Try `%s --help' for more information.\n", program_name);
-                       exit(1);
-                       break;
-               case NO_OPT:
-                       if (optind < argc) {
-                               sethname(argv[optind]);
-                               exit(0);
-                       }
-               default:
-                       printf("%s\n", myname);
-
-       };
-       exit(0);
-}
index 85911211a9d138de7e1a06f0c7dfb945cce3e2e7..6299381374d05fdd8f2639e85f2bc7af26ba6229 100644 (file)
 #include <unistd.h>
 #include <signal.h>
 
-#ifdef __linux__
-/*
- *  sys_signame -- an ordered list of signals.
- *  lifted from /usr/include/linux/signal.h
- *  this particular order is only correct for linux.
- *  this is _not_ portable.
- */
-char *sys_signame[NSIG] = {
-    "zero",  "HUP",  "INT",   "QUIT", "ILL",   "TRAP", "IOT",  "UNUSED",
-    "FPE",   "KILL", "USR1",  "SEGV", "USR2",  "PIPE", "ALRM", "TERM",
-    "STKFLT","CHLD", "CONT",  "STOP", "TSTP",  "TTIN", "TTOU", "IO",
-    "XCPU",  "XFSZ", "VTALRM","PROF", "WINCH", NULL
-};
+#define SIZE(a)        (sizeof(a)/sizeof(a[0]))
+
+struct signv {
+       char *name;
+       int val;
+} sys_signame[] = {
+       /* POSIX signals */
+       { "HUP",        SIGHUP },       /* 1 */
+       { "INT",        SIGINT },       /* 2 */
+       { "QUIT",       SIGQUIT },      /* 3 */
+       { "ILL",        SIGILL },       /* 4 */
+       { "ABRT",       SIGABRT },      /* 6 */
+       { "FPE",        SIGFPE },       /* 8 */
+       { "KILL",       SIGKILL },      /* 9 */
+       { "SEGV",       SIGSEGV },      /* 11 */
+       { "PIPE",       SIGPIPE },      /* 13 */
+       { "ALRM",       SIGALRM },      /* 14 */
+       { "TERM",       SIGTERM },      /* 15 */
+       { "USR1",       SIGUSR1 },      /* 10 (arm,i386,m68k,ppc), 30 (alpha,sparc*), 16 (mips) */
+       { "USR2",       SIGUSR2 },      /* 12 (arm,i386,m68k,ppc), 31 (alpha,sparc*), 17 (mips) */
+       { "CHLD",       SIGCHLD },      /* 17 (arm,i386,m68k,ppc), 20 (alpha,sparc*), 18 (mips) */
+       { "CONT",       SIGCONT },      /* 18 (arm,i386,m68k,ppc), 19 (alpha,sparc*), 25 (mips) */
+       { "STOP",       SIGSTOP },      /* 19 (arm,i386,m68k,ppc), 17 (alpha,sparc*), 23 (mips) */
+       { "TSTP",       SIGTSTP },      /* 20 (arm,i386,m68k,ppc), 18 (alpha,sparc*), 24 (mips) */
+       { "TTIN",       SIGTTIN },      /* 21 (arm,i386,m68k,ppc,alpha,sparc*), 26 (mips) */
+       { "TTOU",       SIGTTOU },      /* 22 (arm,i386,m68k,ppc,alpha,sparc*), 27 (mips) */
+       /* Miscellaneous other signals */
+#ifdef SIGTRAP
+       { "TRAP",       SIGTRAP },      /* 5 */
+#endif
+#ifdef SIGIOT
+       { "IOT",        SIGIOT },       /* 6, same as SIGABRT */
+#endif
+#ifdef SIGEMT
+       { "EMT",        SIGEMT },       /* 7 (mips,alpha,sparc*) */
+#endif
+#ifdef SIGBUS
+       { "BUS",        SIGBUS },       /* 7 (arm,i386,m68k,ppc), 10 (mips,alpha,sparc*) */
+#endif
+#ifdef SIGSYS
+       { "SYS",        SIGSYS },       /* 12 (mips,alpha,sparc*) */
+#endif
+#ifdef SIGSTKFLT
+       { "STKFLT",     SIGSTKFLT },    /* 16 (arm,i386,m68k,ppc) */
+#endif
+#ifdef SIGURG
+       { "URG",        SIGURG },       /* 23 (arm,i386,m68k,ppc), 16 (alpha,sparc*), 21 (mips) */
+#endif
+#ifdef SIGIO
+       { "IO",         SIGIO },        /* 29 (arm,i386,m68k,ppc), 23 (alpha,sparc*), 22 (mips) */
+#endif
+#ifdef SIGPOLL
+       { "POLL",       SIGPOLL },      /* same as SIGIO */
+#endif
+#ifdef SIGCLD
+       { "CLD",        SIGCLD },       /* same as SIGCHLD (mips) */
+#endif
+#ifdef SIGXCPU
+       { "XCPU",       SIGXCPU },      /* 24 (arm,i386,m68k,ppc,alpha,sparc*), 30 (mips) */
 #endif
+#ifdef SIGXFSZ
+       { "XFSZ",       SIGXFSZ },      /* 25 (arm,i386,m68k,ppc,alpha,sparc*), 31 (mips) */
+#endif
+#ifdef SIGVTALRM
+       { "VTALRM",     SIGVTALRM },    /* 26 (arm,i386,m68k,ppc,alpha,sparc*), 28 (mips) */
+#endif
+#ifdef SIGPROF
+       { "PROF",       SIGPROF },      /* 27 (arm,i386,m68k,ppc,alpha,sparc*), 29 (mips) */
+#endif
+#ifdef SIGPWR
+       { "PWR",        SIGPWR },       /* 30 (arm,i386,m68k,ppc), 29 (alpha,sparc*), 19 (mips) */
+#endif
+#ifdef SIGINFO
+       { "INFO",       SIGINFO },      /* 29 (alpha) */
+#endif
+#ifdef SIGLOST
+       { "LOST",       SIGLOST },      /* 29 (arm,i386,m68k,ppc,sparc*) */
+#endif
+#ifdef SIGWINCH
+       { "WINCH",      SIGWINCH },     /* 28 (arm,i386,m68k,ppc,alpha,sparc*), 20 (mips) */
+#endif
+#ifdef SIGUNUSED
+       { "UNUSED",     SIGUNUSED },    /* 31 (arm,i386,m68k,ppc) */
+#endif
+};
 
 int main (int argc, char *argv[]);
 extern char *mybasename(char *);
@@ -197,9 +268,9 @@ int signame_to_signum (char *sig)
 
     if (! strncasecmp (sig, "sig", 3))
        sig += 3;
-    for (n = 1; (n < NSIG) && (sys_signame[n] != NULL); n++) {
-       if (! strcasecmp (sys_signame[n], sig))
-           return n;
+    for (n = 0; n < SIZE(sys_signame); n++) {
+       if (! strcasecmp (sys_signame[n].name, sig))
+           return sys_signame[n].val;
     }
     return (-1);
 }
@@ -226,22 +297,33 @@ void nosig (char *name)
 
 void printsig (int sig)
 {
-    printf ("%s\n", sys_signame[sig]);
+    int n;
+
+    for (n = 0; n < SIZE(sys_signame); n++) {
+       if (sys_signame[n].val == sig) {
+           printf ("%s\n", sys_signame[n].name);
+           return;
+       }
+    }
+    printf("%d\n", sig);
 }
 
 void printsignals (FILE *fp)
 {
-    int n;
+    int n, lth;
+    int lpos = 0;
 
-    for (n = 1; (n < NSIG) && (sys_signame[n] != NULL); n++) {
-       fputs (sys_signame[n], fp);
-       if (n == (NSIG / 2) || n == (NSIG - 1))
+    for (n = 0; n < SIZE(sys_signame); n++) {
+       lth = 1+strlen(sys_signame[n].name);
+       if (lpos+lth > 72) {
            fputc ('\n', fp);
-       else
+           lpos = 0;
+       } else if (lpos)
            fputc (' ', fp);
+       lpos += lth;
+       fputs (sys_signame[n].name, fp);
     }
-    if (n < (NSIG - 1))
-       fputc ('\n', fp);
+    fputc ('\n', fp);
 }
 
 int usage (int status)
index 1d2848b59ef48afcc6496220fd047ee85c70d718..72256c197c5aee77ea9b0c97e68bb97b204215a7 100644 (file)
 #include <string.h>
 #include <ctype.h>
 #include <getopt.h>
+#include <locale.h>
 #include "pathnames.h"
 
-/*
- * FOLD and DICT convert characters to a normal form for comparison,
- * according to the user specified flags.
- * 
- * DICT expects integers because it uses a non-character value to
- * indicate a character which should not participate in comparisons.
- */
 #define        EQUAL           0
 #define        GREATER         1
 #define        LESS            (-1)
-#define NO_COMPARE     (-2)
-
-#define        FOLD(c) (isascii(c) && isupper(c) ? tolower(c) : (c))
-#define        DICT(c) (isascii(c) && isalnum(c) ? (c) : NO_COMPARE)
 
 int dflag, fflag;
+/* uglified the source a bit with globals, so that we only need
+   to allocate comparbuf once */
+int stringlen;
+char *string;
+char *comparbuf;
 
-char   *binary_search __P((char *, char *, char *));
-int     compare __P((char *, char *, char *));
-void    err __P((const char *fmt, ...));
-char   *linear_search __P((char *, char *, char *));
-int     look __P((char *, char *, char *));
-void    print_from __P((char *, char *, char *));
-
-static void usage __P((void));
+static char *binary_search (char *, char *);
+static int compare (char *, char *, int);
+static void err (const char *fmt, ...);
+static char *linear_search (char *, char *);
+static int look (char *, char *);
+static void print_from (char *, char *);
+static void usage (void);
 
-void
-main(argc, argv)
-       int argc;
-       char *argv[];
+int
+main(int argc, char *argv[])
 {
        struct stat sb;
        int ch, fd, termchar;
-       char *back, *file, *front, *string, *p;
+       char *back, *file, *front, *p;
+
+       setlocale(LC_ALL, "");
 
        file = _PATH_WORDS;
        termchar = '\0';
@@ -142,32 +136,35 @@ main(argc, argv)
                                  (off_t)0)) <= (void *)0)
                err("%s: %s", file, strerror(errno));
        back = front + sb.st_size;
-       exit(look(string, front, back));
+       return look(front, back);
 }
 
 int
-look(string, front, back)
-       char *string, *front, *back;
+look(char *front, char *back)
 {
-       register int ch;
-       register char *readp, *writep;
+       int ch;
+       char *readp, *writep;
 
        /* Reformat string string to avoid doing it multiple times later. */
-       for (readp = writep = string; (ch = *readp++) != 0;) {
-               if (fflag)
-                       ch = FOLD(ch);
-               if (dflag)
-                       ch = DICT(ch);
-               if (ch != NO_COMPARE)
-                       *(writep++) = ch;
-       }
-       *writep = '\0';
+       if (dflag) {
+               for (readp = writep = string; (ch = *readp++) != 0;) {
+                       if (isalnum(ch))
+                               *(writep++) = ch;
+               }
+               *writep = '\0';
+               stringlen = writep - string;
+       } else
+               stringlen = strlen(string);
+
+       comparbuf = malloc(stringlen+1);
+       if (comparbuf == NULL)
+               err("Out of memory");
 
-       front = binary_search(string, front, back);
-       front = linear_search(string, front, back);
+       front = binary_search(front, back);
+       front = linear_search(front, back);
 
        if (front)
-               print_from(string, front, back);
+               print_from(front, back);
        return (front ? 0 : 1);
 }
 
@@ -214,10 +211,9 @@ look(string, front, back)
        while (p < back && *p++ != '\n');
 
 char *
-binary_search(string, front, back)
-       register char *string, *front, *back;
+binary_search(char *front, char *back)
 {
-       register char *p;
+       char *p;
 
        p = front + (back - front) / 2;
        SKIP_PAST_NEWLINE(p, back);
@@ -227,7 +223,7 @@ binary_search(string, front, back)
         * infinitely loop.
         */
        while (p < back && back > front) {
-               if (compare(string, p, back) == GREATER)
+               if (compare(p, back, 1) == GREATER)
                        front = p;
                else
                        back = p;
@@ -249,11 +245,10 @@ binary_search(string, front, back)
  *     o front is before or at the first line to be printed.
  */
 char *
-linear_search(string, front, back)
-       char *string, *front, *back;
+linear_search(char *front, char *back)
 {
        while (front < back) {
-               switch (compare(string, front, back)) {
+               switch (compare(front, back, 1)) {
                case EQUAL:             /* Found it. */
                        return (front);
                        break;
@@ -272,20 +267,26 @@ linear_search(string, front, back)
  * Print as many lines as match string, starting at front.
  */
 void 
-print_from(string, front, back)
-       register char *string, *front, *back;
+print_from(char *front, char *back)
 {
-       for (; front < back && compare(string, front, back) == EQUAL; ++front) {
-               for (; front < back && *front != '\n'; ++front)
-                       if (putchar(*front) == EOF)
-                               err("stdout: %s", strerror(errno));
-               if (putchar('\n') == EOF)
-                       err("stdout: %s", strerror(errno));
+       int eol;
+
+       while (front < back && compare(front, back, 1) == EQUAL) {
+               if (compare(front, back, fflag) == EQUAL) {
+                       eol = 0;
+                       while (front < back && !eol) {
+                               if (putchar(*front) == EOF)
+                                       err("stdout: %s", strerror(errno));
+                               if (*front++ == '\n')
+                                       eol = 1;
+                       }
+               } else
+                       SKIP_PAST_NEWLINE(front, back);
        }
 }
 
 /*
- * Return LESS, GREATER, or EQUAL depending on how the string1 compares with
+ * Return LESS, GREATER, or EQUAL depending on how  string  compares with
  * string2 (s1 ??? s2).
  * 
  *     o Matches up to len(s1) are EQUAL. 
@@ -294,32 +295,34 @@ print_from(string, front, back)
  * Compare understands about the -f and -d flags, and treats comparisons
  * appropriately.
  * 
- * The string "s1" is null terminated.  The string s2 is '\n' terminated (or
- * "back" terminated).
+ * The string "string" is null terminated.  The string "s2" is '\n' terminated
+ * (or "s2end" terminated).
+ *
+ * We use strcasecmp etc, since it knows how to ignore case also
+ * in other locales.
  */
 int
-compare(s1, s2, back)
-       register char *s1, *s2, *back;
-{
-       register int ch;
-
-       for (; *s1 && s2 < back && *s2 != '\n';) {
-               ch = *s2;
-               if (fflag)
-                       ch = FOLD(ch);
-               if (dflag)
-                       ch = DICT(ch);
-
-               if (ch == NO_COMPARE) {
-                       ++s2;           /* Ignore character in comparison. */
-                       continue;
-               }
-               if (*s1 != ch)
-                       return (*s1 < ch ? LESS : GREATER);
-               ++s1;
-               ++s2;
+compare(char *s2, char *s2end, int nocase) {
+       int i;
+       char *p;
+
+       /* copy, ignoring things that should be ignored */
+       p = comparbuf;
+       i = stringlen;
+       while(s2 < s2end && *s2 != '\n' && i--) {
+               if (!dflag || isalnum(*s2))
+                       *p++ = *s2;
+               s2++;
        }
-       return (*s1 ? GREATER : EQUAL);
+       *p = 0;
+
+       /* and compare */
+       if (nocase)
+               i = strncasecmp(comparbuf, string, stringlen);
+       else
+               i = strncmp(comparbuf, string, stringlen);
+
+       return ((i > 0) ? LESS : (i < 0) ? GREATER : EQUAL);
 }
 
 static void
index 6d3a11c3031ad44f0fcaca1ffa14d9555ad13427..c6667e2173ab16a9ae73d9875563d1d4a5440c02 100644 (file)
@@ -19,10 +19,11 @@ process id, the parent process id, the contents of an input file (if
 .B \-f
 is specified), and several bytes of information from the first of the
 following devices which is present:
-.IR /dev/urandom ", " /dev/random ", " /dev/audio .
-Other files in
-.I /proc
-may be used as a last resort.
+.IR /dev/random ,
+.IR /dev/urandom ,
+files in
+.IR /proc ,
+.IR /dev/audio .
 .SH BUGS
 The entropy in the generated 128-bit is probably quite small (and,
 therefore, vulnerable to attack) unless a non-pseudorandom number generator
index 05136190fa2f2b34fc85948279432dd3438fd7f5..33ae7630e1c052d55173022b39b2f1c1c956bac0 100644 (file)
@@ -101,9 +101,12 @@ int main( int argc, char **argv )
    }
 
    for (i = 0; i < RNGS; i++) {
-      if ((fd = open( rngs[i].path, O_RDONLY )) >= 0) {
+      if ((fd = open( rngs[i].path, O_RDONLY|O_NONBLOCK )) >= 0) {
         r = read( fd, buf, sizeof( buf ) );
-        MD5Update( &ctx, buf, r );
+        if (r > 0)
+           MD5Update( &ctx, buf, r );
+        else
+           r = 0;
         close( fd );
         if (Verbose)
            fprintf( stderr, "Got %d bytes from %s\n", r, rngs[i].path );
index 2ea3e098c8869f5a4989804566745f3fa4388eb4..fd0e5add36547a8954319c601a893026de819005 100644 (file)
@@ -6,9 +6,9 @@
  *   modify it under the terms of the gnu general public license.
  *   there is no warranty.
  *
- *   $Author: janl $
- *   $Revision: 1.5 $
- *   $Date: 1996/11/11 22:40:03 $
+ *   faith
+ *   1.2
+ *   1995/02/23 01:20:40
  *
  */
 
@@ -112,7 +112,6 @@ static char *parse_parens (char *buf)
     return cp;
 }
 
-
 char *mybasename (char *path)
 {
     char *cp;
@@ -120,3 +119,4 @@ char *mybasename (char *path)
     cp = strrchr (path, '/');
     return (cp ? cp + 1 : path);
 }
+
index af4013d30c65685b96489951dec09e794bad8fc8..23c48ea6bd372595204850dd7b9c1697b19cae4c 100644 (file)
 #include <string.h>
 #endif
 
+#ifdef HAVE_OPENPTY
+#include <pty.h>
+#endif
+
 void done(void);
 void fail(void);
 void fixtty(void);
@@ -70,10 +74,12 @@ struct      termios tt;
 struct winsize win;
 int    lb;
 int    l;
+#ifndef HAVE_OPENPTY
 char   line[] = "/dev/ptyXX";
+#endif
 int    aflg;
 
-void
+int
 main(argc, argv)
        int argc;
        char *argv[];
@@ -131,6 +137,8 @@ main(argc, argv)
                        doshell();
        }
        doinput();
+
+       return 0;
 }
 
 void
@@ -140,6 +148,9 @@ doinput()
        char ibuf[BUFSIZ];
 
        (void) fclose(fscript);
+#ifdef HAVE_OPENPTY
+       (void) close(slave);
+#endif
        while ((cc = read(0, ibuf, BUFSIZ)) > 0)
                (void) write(master, ibuf, cc);
        done();
@@ -170,6 +181,9 @@ dooutput()
        char obuf[BUFSIZ], *ctime();
 
        (void) close(0);
+#ifdef HAVE_OPENPTY
+       (void) close(slave);
+#endif
        tvec = time((time_t *)NULL);
        fprintf(fscript, "Script started on %s", ctime(&tvec));
        for (;;) {
@@ -250,6 +264,14 @@ done()
 void
 getmaster()
 {
+#ifdef HAVE_OPENPTY
+       (void) tcgetattr(0, &tt);
+       (void) ioctl(0, TIOCGWINSZ, (char *)&win);
+       if (openpty(&master, &slave, NULL, &tt, &win) < 0) {
+               fprintf(stderr, "openpty failed\n");
+               fail();
+       }
+#else
        char *pty, *bank, *cp;
        struct stat stb;
 
@@ -282,12 +304,13 @@ getmaster()
        }
        fprintf(stderr, "Out of pty's\n");
        fail();
+#endif /* not HAVE_OPENPTY */
 }
 
 void
 getslave()
 {
-
+#ifndef HAVE_OPENPTY
        line[strlen("/dev/")] = 't';
        slave = open(line, O_RDWR);
        if (slave < 0) {
@@ -296,6 +319,7 @@ getslave()
        }
        (void) tcsetattr(slave, TCSAFLUSH, &tt);
        (void) ioctl(slave, TIOCSWINSZ, (char *)&win);
+#endif
        (void) setsid();
        (void) ioctl(slave, TIOCSCTTY, 0);
 }
index 49903f3b770edcccf60d21d8b265ae586a9d2f50..3b3e6c24fcf833d1a6ff869b5ef090a0d700d226 100644 (file)
@@ -95,6 +95,9 @@
 #include <termios.h>
 #include <string.h>
 #include <fcntl.h>
+#ifndef NCURSES_CONST
+#define NCURSES_CONST const    /* define before including term.h */
+#endif
 #include <term.h>
 #if NCH
 #include <ncurses.h>
@@ -928,11 +931,12 @@ int vcterm;                       /* Set if terminal is a virtual console. */
   /* -inversescreen [on|off].  Vc only (vt102).
    */
   if (opt_inversescreen) {
-       if (vcterm)
+       if (vcterm) {
                if (opt_invsc_on)
                        printf("\033[?5h");
                else
                        printf("\033[?5l");
+       }
   }
 
   /* -bold [on|off].  Vc behaves as expected, otherwise off turns off
index 1a8e1edd741da20196fd2f748f801e7616c303ab..49419241716706fe94def8b2178fe04772395f54 100644 (file)
@@ -99,6 +99,8 @@ static char *bindirs[] = {
    "/usr/libexec",
    "/usr/share",
 
+   "/opt/*/bin",
+
        0
 };
 
index e43b0bf9a426ef6c5d40c13360f079f3de48d805..07a113ea726437163b0fb1f3e36a350d86ed8fac 100644 (file)
@@ -48,6 +48,7 @@
 #include <pwd.h>
 #include <stdio.h>
 #include <string.h>
+#include <locale.h>
 #include <sys/param.h>
 #include <sys/signal.h>
 #include <sys/stat.h>
@@ -56,7 +57,6 @@
 #ifdef __linux__
 #include <paths.h>
 #include "pathnames.h"
-#include <locale.h>
 #endif
 
 void search_utmp(char *, char *, char *, uid_t);
@@ -67,7 +67,7 @@ int utmp_chk(char *, char *);
 
 extern int errno;
 
-void
+int
 main(int argc, char **argv)
 {
        register char *cp;
@@ -77,9 +77,7 @@ main(int argc, char **argv)
        char tty[MAXPATHLEN], *mytty, *ttyname();
        void done();
 
-#ifdef __linux__
        setlocale(LC_CTYPE,"");
-#endif
 
        /* check that sender has write enabled */
        if (isatty(fileno(stdin)))
@@ -143,6 +141,7 @@ main(int argc, char **argv)
        }
        done();
        /* NOTREACHED */
+       return 0;
 }
 
 
@@ -291,11 +290,12 @@ void do_write(char *tty, char *mytty, uid_t myuid)
        void done();
 
        /* Determine our login name before the we reopen() stdout */
-       if ((login = getlogin()) == NULL)
+       if ((login = getlogin()) == NULL) {
                if ((pwd = getpwuid(myuid)) != NULL)
                        login = pwd->pw_name;
                else
                        login = "???";
+       }
 
        if (strlen(tty) + 6 > sizeof(path))
                exit(1);
@@ -347,8 +347,13 @@ void wr_fputs(char *s)
                        PUTC('\r');
                        PUTC('\n');
                } else if (!isprint(c) && !isspace(c) && c != '\007') {
-                       PUTC('^');
-                       PUTC(c^0x40);   /* DEL to ?, others to alpha */
+                       if (c & 0x80) {
+                               /* use some fallback? */
+                               (void)printf("\\%3o", (unsigned char) c);
+                       } else {
+                               PUTC('^');
+                               PUTC(c^0x40);   /* DEL to ?, others to alpha */
+                       }
                } else
                        PUTC(c);
        }
diff --git a/mkminix-0.1/README b/mkminix-0.1/README
new file mode 100644 (file)
index 0000000..d93c38e
--- /dev/null
@@ -0,0 +1,47 @@
+Mkminix-0.1 by W. Black
+
+Description
+-----------
+This directory contains a hacked version of mkfs.minix from util-linux 2.8.
+The hack in question was primarily a bit of #ifndef-ing to make it compile
+successfully under DJGPP.  Due to DOS's brain-damaged 8.3 filename limitation,
+the executable has been renamed from mkfs.minix to mkminix.exe.
+[Executable deleted in the util-linux distribution.]
+
+Distribution
+------------
+This distribution should have come with both sources and executable.  If
+you're missing either, feel free to visit my site at 
+http://www.geocities.com/SiliconValley/Network/5508 to get a fresh one if
+you need it.
+
+This program and its source program in util-linux are protected by the GNU
+General Public License.  See the file COPYING for details.
+
+Why
+---
+Exactly why would anyone want to create a Minix filesystem under DOS?  The
+answer, as far as I am concerned, is in the interest of creating initial 
+ramdisks for Linux.  By being able to configure an initrd from DOS (or Win
+'95, etc.), you can make the transition to Linux that much easier (think
+Win '95 autoplay Linux distributions, for example).
+
+Phase II of this project would logically be to be able to populate this initrd
+with files.  That is my goal for mkminix-0.2.
+
+Installation
+------------
+At this point, everything is pretty much already installed.  Just run MKMINIX
+from the DOS prompt.  The source will compile under DJGPP if and only if you
+have a copy of linux/minix_fs.h.  I included the one from Linux kernel 2.0.30,
+but these files have a way of changing in annoying ways, so it's probably best
+to use one that matches whatever version of Linux you are going to be running
+concurrently.  This is if you have to be ABSOLUTELY sure that everything
+matches...  BTW, compile line is as follows for DJGPP:  
+
+  gcc -o mkminix.exe mkminix.c
+
+Desperate Plea for Attention
+----------------------------
+If you find this program useful (or silly, or a complete waste of time), please
+drop me a line at wjblack@yahoo.com.  Thanks!
diff --git a/mkminix-0.1/linux/minix_fs.h b/mkminix-0.1/linux/minix_fs.h
new file mode 100644 (file)
index 0000000..3bc020f
--- /dev/null
@@ -0,0 +1,135 @@
+#ifndef _LINUX_MINIX_FS_H
+#define _LINUX_MINIX_FS_H
+
+/*
+ * The minix filesystem constants/structures
+ */
+
+/*
+ * Thanks to Kees J Bot for sending me the definitions of the new
+ * minix filesystem (aka V2) with bigger inodes and 32-bit block
+ * pointers.
+ */
+
+#define MINIX_ROOT_INO 1
+
+/* Not the same as the bogus LINK_MAX in <linux/limits.h>. Oh well. */
+#define MINIX_LINK_MAX 250
+
+#define MINIX_I_MAP_SLOTS      8
+#define MINIX_Z_MAP_SLOTS      64
+#define MINIX_SUPER_MAGIC      0x137F          /* original minix fs */
+#define MINIX_SUPER_MAGIC2     0x138F          /* minix fs, 30 char names */
+#define MINIX2_SUPER_MAGIC     0x2468          /* minix V2 fs */
+#define MINIX2_SUPER_MAGIC2    0x2478          /* minix V2 fs, 30 char names */
+#define MINIX_VALID_FS         0x0001          /* Clean fs. */
+#define MINIX_ERROR_FS         0x0002          /* fs has errors. */
+
+#define MINIX_INODES_PER_BLOCK ((BLOCK_SIZE)/(sizeof (struct minix_inode)))
+#define MINIX2_INODES_PER_BLOCK ((BLOCK_SIZE)/(sizeof (struct minix2_inode)))
+
+#define MINIX_V1               0x0001          /* original minix fs */
+#define MINIX_V2               0x0002          /* minix V2 fs */
+
+#define INODE_VERSION(inode)   inode->i_sb->u.minix_sb.s_version
+
+/*
+ * This is the original minix inode layout on disk.
+ * Note the 8-bit gid and atime and ctime.
+ */
+struct minix_inode {
+       __u16 i_mode;
+       __u16 i_uid;
+       __u32 i_size;
+       __u32 i_time;
+       __u8  i_gid;
+       __u8  i_nlinks;
+       __u16 i_zone[9];
+};
+
+/*
+ * The new minix inode has all the time entries, as well as
+ * long block numbers and a third indirect block (7+1+1+1
+ * instead of 7+1+1). Also, some previously 8-bit values are
+ * now 16-bit. The inode is now 64 bytes instead of 32.
+ */
+struct minix2_inode {
+       __u16 i_mode;
+       __u16 i_nlinks;
+       __u16 i_uid;
+       __u16 i_gid;
+       __u32 i_size;
+       __u32 i_atime;
+       __u32 i_mtime;
+       __u32 i_ctime;
+       __u32 i_zone[10];
+};
+
+/*
+ * minix super-block data on disk
+ */
+struct minix_super_block {
+       __u16 s_ninodes;
+       __u16 s_nzones;
+       __u16 s_imap_blocks;
+       __u16 s_zmap_blocks;
+       __u16 s_firstdatazone;
+       __u16 s_log_zone_size;
+       __u32 s_max_size;
+       __u16 s_magic;
+       __u16 s_state;
+       __u32 s_zones;
+};
+
+struct minix_dir_entry {
+       __u16 inode;
+       char name[0];
+};
+
+#ifdef __KERNEL__
+
+extern int minix_lookup(struct inode * dir,const char * name, int len,
+                        struct inode ** result);
+extern int minix_create(struct inode * dir,const char * name, int len, int mode,
+       struct inode ** result);
+extern int minix_mkdir(struct inode * dir, const char * name, int len, int mode);
+extern int minix_rmdir(struct inode * dir, const char * name, int len);
+extern int minix_unlink(struct inode * dir, const char * name, int len);
+extern int minix_symlink(struct inode * inode, const char * name, int len,
+       const char * symname);
+extern int minix_link(struct inode * oldinode, struct inode * dir, const char * name, int len);
+extern int minix_mknod(struct inode * dir, const char * name, int len, int mode, int rdev);
+extern int minix_rename(struct inode * old_dir, const char * old_name, int old_len,
+       struct inode * new_dir, const char * new_name, int new_len, int must_be_dir);
+extern struct inode * minix_new_inode(const struct inode * dir);
+extern void minix_free_inode(struct inode * inode);
+extern unsigned long minix_count_free_inodes(struct super_block *sb);
+extern int minix_new_block(struct super_block * sb);
+extern void minix_free_block(struct super_block * sb, int block);
+extern unsigned long minix_count_free_blocks(struct super_block *sb);
+
+extern int minix_bmap(struct inode *,int);
+
+extern struct buffer_head * minix_getblk(struct inode *, int, int);
+extern struct buffer_head * minix_bread(struct inode *, int, int);
+
+extern void minix_truncate(struct inode *);
+extern void minix_put_super(struct super_block *);
+extern struct super_block *minix_read_super(struct super_block *,void *,int);
+extern int init_minix_fs(void);
+extern void minix_write_super(struct super_block *);
+extern int minix_remount (struct super_block * sb, int * flags, char * data);
+extern void minix_read_inode(struct inode *);
+extern void minix_write_inode(struct inode *);
+extern void minix_put_inode(struct inode *);
+extern void minix_statfs(struct super_block *, struct statfs *, int);
+extern int minix_sync_inode(struct inode *);
+extern int minix_sync_file(struct inode *, struct file *);
+
+extern struct inode_operations minix_file_inode_operations;
+extern struct inode_operations minix_dir_inode_operations;
+extern struct inode_operations minix_symlink_inode_operations;
+
+#endif /* __KERNEL__ */
+
+#endif
diff --git a/mkminix-0.1/mkmin-dj.h b/mkminix-0.1/mkmin-dj.h
new file mode 100644 (file)
index 0000000..1ed7b21
--- /dev/null
@@ -0,0 +1,43 @@
+/* Stolen from linux/fs.h */\r
+#define BLOCK_SIZE 1024\r
+\r
+/* Ugh */\r
+typedef unsigned char __u8;\r
+typedef unsigned short __u16;\r
+typedef unsigned int __u32;\r
+\r
+/* Stolen from linux/stat.h, since DJGPP's stat.h produces different values */\r
+#define S_IFMT  00170000\r
+#define S_IFSOCK 0140000\r
+#define S_IFLNK  0120000\r
+#define S_IFREG  0100000\r
+#define S_IFBLK  0060000\r
+#define S_IFDIR  0040000\r
+#define S_IFCHR  0020000\r
+#define S_IFIFO  0010000\r
+#define S_ISUID  0004000\r
+#define S_ISGID  0002000\r
+#define S_ISVTX  0001000\r
+\r
+#define S_ISLNK(m)      (((m) & S_IFMT) == S_IFLNK)\r
+#define S_ISREG(m)      (((m) & S_IFMT) == S_IFREG)\r
+#define S_ISDIR(m)      (((m) & S_IFMT) == S_IFDIR)\r
+#define S_ISCHR(m)      (((m) & S_IFMT) == S_IFCHR)\r
+#define S_ISBLK(m)      (((m) & S_IFMT) == S_IFBLK)\r
+#define S_ISFIFO(m)     (((m) & S_IFMT) == S_IFIFO)\r
+#define S_ISSOCK(m)     (((m) & S_IFMT) == S_IFSOCK)\r
+\r
+#define S_IRWXU 00700\r
+#define S_IRUSR 00400\r
+#define S_IWUSR 00200\r
+#define S_IXUSR 00100\r
+\r
+#define S_IRWXG 00070\r
+#define S_IRGRP 00040\r
+#define S_IWGRP 00020\r
+#define S_IXGRP 00010\r
+\r
+#define S_IRWXO 00007\r
+#define S_IROTH 00004\r
+#define S_IWOTH 00002\r
+#define S_IXOTH 00001\r
diff --git a/mkminix-0.1/mkminix.diff b/mkminix-0.1/mkminix.diff
new file mode 100644 (file)
index 0000000..45d6c81
--- /dev/null
@@ -0,0 +1,46 @@
+48a49,51
+>  * 09.29.98  -  Modified to compile under DJGPP (minus mount-checking, etc.).
+>  *              (wjblack@yahoo.com)
+>  *
+69a73,78
+> 
+> /* DJGPP's IOCTL interface should probably not be trusted here.  It's not
+>    needed, anyway.  Nor does DJGPP have any clue about mounted filesystems.
+>    Oh, did I mention that the directory status, etc, doesn't match that of
+>    the Minix FS? */
+> #ifndef __DJGPP__
+74a84,91
+> #endif
+> 
+> /* For those defs that DJGPP doesn't have (or has wrong) */
+> #ifdef __DJGPP__
+> #include "mkmin-dj.h"
+> #endif
+> 
+> /* DJGPP requires that you stick a linux/minix_fs.h somewhere appropriate */
+172a190
+> #ifndef __DJGPP__
+173a192,194
+> #else
+> #define usage() fatal_error("Usage: %s [-c | -l filename] [-nXX] [-iXX] imagefile [blocks]\n",16)
+> #endif
+175a197
+> #ifndef __DJGPP__
+196a219
+> #endif                               /* __DJGPP__ */
+238a262
+> #ifndef __DJGPP__
+242a267
+> #endif
+613a639
+> #ifndef __DJGPP__
+614a641
+> #endif
+694a722
+> #ifndef __DJGPP__
+695a724
+> #endif
+707a737
+> #ifndef __DJGPP__
+713a744
+> #endif
index 32272a9b6f4d0a7b8d01369a235f105270d569bb..c61b4ae8c26d923e77fce156d26c64cb13aaf16c 100644 (file)
@@ -3,18 +3,17 @@ include ../MCONFIG
 endif
 
 CC = gcc
-CFLAGS = -O2
+CFLAGS = -I$(LIB) $(OPT)
 WARNFLAGS = -Wall -Wstrict-prototypes -Wmissing-prototypes
 DEFINES = -DHAVE_NFS
-LDFLAGS =
 
 RPCSVCDIR = rpcsvc
 RPC_CFLAGS = -Wno-unused 
 RPCGEN = rpcgen
 #INSTALL = install
-#INSTALL_SUID = $(INSTALL) -m 4755 -o root
-#INSTALL_PROG = $(INSTALL) -m 755
-#INSTALL_DATA = $(INSTALL) -m 644
+#INSTALLSUID = $(INSTALL) -m 4755 -o root
+#INSTALLPROG = $(INSTALL) -m 755
+#INSTALLDATA = $(INSTALL) -m 644
 
 ## for suid progs (mount, umount)
 #BINDIR = /bin
@@ -54,32 +53,43 @@ install: $(PROGS)
 %.o: %.c
        $(COMPILE) $<
 
-mount: mount.o fstab.o sundries.o realpath.o version.o $(NFS_OBJS) $(LO_OBJS)
-       $(LINK) $^ $(LDLIBS) -o $@
+mount: mount.o fstab.o sundries.o realpath.o mntent.o version.o \
+       mount_guess_fstype.o mount_by_label.o getusername.o \
+       $(LIB)/setproctitle.o $(NFS_OBJS) $(LO_OBJS)
+       $(LINK) $^ -o $@
 
-umount: umount.o fstab.o sundries.o realpath.o version.o $(LO_OBJS)
-       $(LINK) $^ $(LDLIBS) -o $@
+umount: umount.o fstab.o sundries.o realpath.o mntent.o getusername.o \
+       version.o $(LO_OBJS)
+       $(LINK) $^ -o $@
 
 swapon:        swapon.o version.o
-       $(LINK) $^ $(LDLIBS) -o $@
+       $(LINK) $^ -o $@
 
 losetup: losetup.o
-       $(LINK) $^ $(LDLIBS) -o $@
-
-mount.o: linux_fs.h
+       $(LINK) $^ -o $@
 
 mount.o umount.o nfsmount.o losetup.o fstab.o sundries.o: sundries.h
 
 mount.o umount.o fstab.o sundries.o: fstab.h
 
+mount.o fstab.o mntent.o: mntent.h
+
+mount.o mount_guess_fstype.o: mount_guess_fstype.h
+
+mount.o: $(LIB)/setproctitle.h
+
+mount.o umount.o getusername.o: getusername.h
+
 mount.o umount.o losetup.o lomount.o: lomount.h loop.h
 
-swapon.o: swap.h swapargs.h
+swapon.o: swap_constants.h swapargs.h
 
 sundries.o nfsmount.o nfsmount_xdr.o nfsmount_clnt.o: nfsmount.h
 
 umount.o: mount_constants.h
 
+mount.o mount_by_label.o mount_guess_fstype.o: linux_fs.h
+
 nfsmount_clnt.o: nfsmount_clnt.c
        $(COMPILE) $(RPC_CFLAGS) nfsmount_clnt.c
 
@@ -109,11 +119,6 @@ nfs_mountversion.h:
                echo '#define KERNEL_NFS_MOUNT_VERSION 0'; \
        fi > nfs_mountversion.h
 
-SWAPH=/usr/include/linux/swap.h
-swap.h:
-       rm -f swap.h
-       if [ -f $(SWAPH) ]; then cp $(SWAPH) .; else touch swap.h; fi
-
 swapargs.h:
        sh swap.configure
 
@@ -122,7 +127,7 @@ loop.h:
 
 clean:
        rm -f a.out core *~ *.o swapargs.h $(PROGS) swapoff
-       rm -f swap.h loop.h nfs_mountversion.h
+       rm -f loop.h nfs_mountversion.h
 
 clobber distclean realclean: clean
 #      rm -f $(GEN_FILES)
index 2cedcd235c06d97e7617c1b68e0d5e09bf9efa0f..1be3756892def3dc89ffc1a0e0eb93dab93afd33 100644 (file)
@@ -5,7 +5,7 @@
 # For now: a standalone version
 
 CC = gcc
-CFLAGS = -O2
+CFLAGS = -O2 -I../lib
 
 #WARNFLAGS = -Wall -Wstrict-prototypes
 # We really want
@@ -23,11 +23,11 @@ RPC_CFLAGS = -Wno-unused
 RPCGEN = rpcgen
 
 INSTALL = install
-INSTALL_SUID = $(INSTALL) -m 4755 -o root
-INSTALL_PROG = $(INSTALL) -m 755
-INSTALL_DATA = $(INSTALL) -m 644
-INSTALL_DIR = mkdir -p
-INSTALL_MAN = $(INSTALL_DATA)
+INSTALLSUID = $(INSTALL) -m 4755 -o root
+INSTALLPROG = $(INSTALL) -m 755
+INSTALLDATA = $(INSTALL) -m 644
+INSTALLDIR = mkdir -p
+INSTALLMAN = $(INSTALLDATA)
 
 MANDIR = /usr/man
 ## for suid progs (mount, umount)
@@ -57,21 +57,22 @@ LO_OBJS=lomount.o
 all: $(PROGS)
 
 install: $(PROGS)
-       $(INSTALL_DIR) $(BINDIR) $(SBINDIR)
-       $(INSTALL_SUID) -s $(SUID_PROGS) $(BINDIR)
-       $(INSTALL_PROG) -s $(NOSUID_PROGS) $(SBINDIR)
+       $(INSTALLDIR) $(BINDIR) $(SBINDIR)
+       $(INSTALLSUID) -s $(SUID_PROGS) $(BINDIR)
+       $(INSTALLPROG) -s $(NOSUID_PROGS) $(SBINDIR)
        (cd $(SBINDIR); ln -sf swapon swapoff)
-       $(INSTALL_DIR) $(MANDIR)/man5 $(MANDIR)/man8
-       $(INSTALL_MAN) $(MAN5) $(MANDIR)/man5
-       $(INSTALL_MAN) $(MAN8) $(MANDIR)/man8
+       $(INSTALLDIR) $(MANDIR)/man5 $(MANDIR)/man8
+       $(INSTALLMAN) $(MAN5) $(MANDIR)/man5
+       $(INSTALLMAN) $(MAN8) $(MANDIR)/man8
 
 %.o: %.c
        $(COMPILE) $<
 
-mount: mount.o fstab.o sundries.o realpath.o version.o $(NFS_OBJS) $(LO_OBJS)
+mount: mount.o fstab.o sundries.o realpath.o mntent.o version.o \
+       mount_guess_fstype.o mount_by_label.o ../lib/setproctitle.o $(NFS_OBJS) $(LO_OBJS)
        $(LINK) $^ -o $@
 
-umount: umount.o fstab.o sundries.o realpath.o version.o $(LO_OBJS)
+umount: umount.o fstab.o sundries.o realpath.o mntent.o version.o $(LO_OBJS)
        $(LINK) $^ -o $@
 
 swapon:        swapon.o version.o
@@ -84,14 +85,20 @@ mount.o umount.o nfsmount.o losetup.o fstab.o sundries.o: sundries.h
 
 mount.o umount.o fstab.o sundries.o: fstab.h
 
-mount.o umount.o losetup.o: lomount.h loop.h
+mount.o fstab.o mntent.o: mntent.h
 
-swapon.o: swap.h swapargs.h
+mount.o mount_guess_fstype.o: mount_guess_fstype.h
+
+mount.o umount.o losetup.o lomount.o: lomount.h loop.h
+
+swapon.o: swap_constants.h swapargs.h
 
 sundries.o nfsmount.o nfsmount_xdr.o nfsmount_clnt.o: nfsmount.h
 
 umount.o: mount_constants.h
 
+mount.o mount_by_label.o mount_guess_fstype.o: linux_fs.h
+
 nfsmount_clnt.o: nfsmount_clnt.c
        $(COMPILE) $(RPC_CFLAGS) nfsmount_clnt.c
 
@@ -110,8 +117,6 @@ nfsmount.x:
 nfsmount.o: nfs_mountversion.h nfs_mount3.h
 
 NFSMOUNTH=/usr/include/linux/nfs_mount.h
-SWAPH=/usr/include/linux/swap.h
-LOOPH=/usr/include/linux/loop.h
 
 nfs_mountversion.h:
        rm -f nfs_mountversion.h
@@ -122,20 +127,15 @@ nfs_mountversion.h:
                echo '#define KERNEL_NFS_MOUNT_VERSION 0'; \
        fi > nfs_mountversion.h
 
-swap.h:
-       rm -f swap.h
-       if [ -f $(SWAPH) ]; then cp $(SWAPH) .; else touch swap.h; fi
-
 swapargs.h:
        sh swap.configure
 
 loop.h:
-       rm -f loop.h
-       if [ -f $(LOOPH) ]; then cp $(LOOPH) .; else touch loop.h; fi
+       sh mk_loop_h
 
 clean:
        rm -f a.out core *~ *.o swapargs.h $(PROGS) swapoff
-       rm -f swap.h loop.h nfs_mountversion.h
+       rm -f loop.h nfs_mountversion.h
 
 clobber distclean realclean: clean
        rm -f $(GEN_FILES)
index 8af521b2fc366eb94da0dd1ed07fa40d6888d0bc..d343538db6c56dbfaf19b10850aca97dd7071c03 100644 (file)
@@ -111,7 +111,7 @@ a filesystem for mounting partitions from remote systems.
 a disk partition to be used for swapping.
 .PP
 If
-.I vfs_fstype
+.I fs_vfstype
 is specified as ``ignore'' the entry is ignored.  This is useful to show
 disk partitions which are currently unused.
 
index 6a2adc65713bec9bcf3357e6735b7b3099743ccb..a67316ee92e097758ae6cd6f5f93962057ced52c 100644 (file)
@@ -1,9 +1,9 @@
 #include <unistd.h>
-#include <mntent.h>
 #include <errno.h>
 #include <stdio.h>
 #include <string.h>
 #include <sys/stat.h>
+#include "mntent.h"
 #include "fstab.h"
 #include "sundries.h"          /* for xmalloc() etc */
 
@@ -88,30 +88,28 @@ fstab_head() {
 }
 
 static void
-read_mntentchn(FILE *fp, const char *fnam, struct mntentchn *mc0) {
-     struct mntentchn *mc = mc0;
-     struct mntent *mnt;
-
-     while (!feof(fp) && !ferror(fp)) {
-         if ((mnt = getmntent (fp)) != NULL           /* ignore blank lines */
-              && *mnt->mnt_fsname != '#'              /* and comment lines */
-              && !streq (mnt->mnt_type, MNTTYPE_IGNORE)) {
-              mc->nxt = (struct mntentchn *) xmalloc(sizeof(*mc));
-              mc->nxt->prev = mc;
-              mc = mc->nxt;
-              mc->mnt_fsname = xstrdup(mnt->mnt_fsname);
-              mc->mnt_dir = xstrdup(mnt->mnt_dir);
-              mc->mnt_type = xstrdup(mnt->mnt_type);
-              mc->mnt_opts = xstrdup(mnt->mnt_opts);
-              mc->nxt = NULL;
-         }
-     }
-     mc0->prev = mc;
-     if (ferror (fp)) {
-         error("warning: error reading %s: %s", fnam, strerror (errno));
-         mc0->nxt = mc0->prev = NULL;
-     }
-     endmntent(fp);
+read_mntentchn(mntFILE *mfp, const char *fnam, struct mntentchn *mc0) {
+       struct mntentchn *mc = mc0;
+       struct mntent *mnt;
+
+       while ((mnt = my_getmntent (mfp)) != NULL) {
+           if (!streq (mnt->mnt_type, MNTTYPE_IGNORE)) {
+               mc->nxt = (struct mntentchn *) xmalloc(sizeof(*mc));
+               mc->nxt->prev = mc;
+               mc = mc->nxt;
+               mc->mnt_fsname = mnt->mnt_fsname;
+               mc->mnt_dir = mnt->mnt_dir;
+               mc->mnt_type = mnt->mnt_type;
+               mc->mnt_opts = mnt->mnt_opts;
+               mc->nxt = NULL;
+           }
+       }
+       mc0->prev = mc;
+       if (ferror (mfp->mntent_fp)) {
+               error("warning: error reading %s: %s", fnam, strerror (errno));
+               mc0->nxt = mc0->prev = NULL;
+       }
+       my_endmntent(mfp);
 }
 
 /*
@@ -121,7 +119,7 @@ read_mntentchn(FILE *fp, const char *fnam, struct mntentchn *mc0) {
  */
 static void
 read_mounttable() {
-     FILE *fp = NULL;
+     mntFILE *mfp;
      const char *fnam;
      struct mntentchn *mc = &mounttable;
 
@@ -129,10 +127,12 @@ read_mounttable() {
      mc->nxt = mc->prev = NULL;
 
      fnam = MOUNTED;
-     if ((fp = setmntent (fnam, "r")) == NULL) {
+     mfp = my_setmntent (fnam, "r");
+     if (mfp == NULL || mfp->mntent_fp == NULL) {
          int errsv = errno;
          fnam = PROC_MOUNTS;
-         if ((fp = setmntent (fnam, "r")) == NULL) {
+         mfp = my_setmntent (fnam, "r");
+         if (mfp == NULL || mfp->mntent_fp == NULL) {
               error("warning: can't open %s: %s", MOUNTED, strerror (errsv));
               return;
          }
@@ -140,12 +140,12 @@ read_mounttable() {
               printf ("mount: could not open %s - using %s instead\n",
                       MOUNTED, PROC_MOUNTS);
      }
-     read_mntentchn(fp, fnam, mc);
+     read_mntentchn(mfp, fnam, mc);
 }
 
 static void
 read_fstab() {
-     FILE *fp = NULL;
+     mntFILE *mfp = NULL;
      const char *fnam;
      struct mntentchn *mc = &fstab;
 
@@ -153,11 +153,12 @@ read_fstab() {
      mc->nxt = mc->prev = NULL;
 
      fnam = _PATH_FSTAB;
-     if ((fp = setmntent (fnam, "r")) == NULL) {
+     mfp = my_setmntent (fnam, "r");
+     if (mfp == NULL || mfp->mntent_fp == NULL) {
          error("warning: can't open %s: %s", _PATH_FSTAB, strerror (errno));
          return;
      }
-     read_mntentchn(fp, fnam, mc);
+     read_mntentchn(mfp, fnam, mc);
 }
      
 
@@ -173,6 +174,24 @@ getmntfile (const char *name) {
     return mc;
 }
 
+/*
+ * Given the name NAME, and the place MCPREV we found it last time,
+ * try to find more occurrences.
+ */ 
+struct mntentchn *
+getmntfilesbackward (const char *name, struct mntentchn *mcprev) {
+    struct mntentchn *mc, *mh;
+
+    mh = mtab_head();
+    if (!mcprev)
+       mcprev = mh;
+    for (mc = mcprev->prev; mc && mc != mh; mc = mc->prev)
+        if (streq (mc->mnt_dir, name) || (streq (mc->mnt_fsname, name)))
+           return mc;
+
+    return NULL;
+}
+
 /* Given the name FILE, try to find the option "loop=FILE" in mtab.  */ 
 struct mntentchn *
 getmntoptfile (const char *file)
@@ -222,13 +241,41 @@ getfsspec (const char *spec)
     return mc;
 }
 
-/* Updating mtab ----------------------------------------------*/
+/* Find the uuid UUID in fstab. */
+struct mntentchn *
+getfsuuidspec (const char *uuid)
+{
+    struct mntentchn *mc;
+
+    for (mc = fstab_head()->nxt; mc; mc = mc->nxt)
+       if (strncmp (mc->mnt_fsname, "UUID=", 5) == 0
+           && streq(mc->mnt_fsname + 5, uuid))
+           break;
+
+    return mc;
+}
 
-/* File descriptor for lock.  Value tested in unlock_mtab() to remove race.  */
-static int lock = -1;
+/* Find the label LABEL in fstab. */
+struct mntentchn *
+getfsvolspec (const char *label)
+{
+    struct mntentchn *mc;
+
+    for (mc = fstab_head()->nxt; mc; mc = mc->nxt)
+       if (strncmp (mc->mnt_fsname, "LABEL=", 6) == 0
+           && streq(mc->mnt_fsname + 6, label))
+           break;
+
+    return mc;
+}
+
+/* Updating mtab ----------------------------------------------*/
 
 /* Flag for already existing lock file. */
-static int old_lockfile = 1;
+static int we_created_lockfile = 0;
+
+/* Flag to indicate that signals have been set up. */
+static int signals_have_been_setup = 0;
 
 /* Ensure that the lock is released if we are interrupted.  */
 static void
@@ -241,69 +288,122 @@ setlkw_timeout (int sig) {
      /* nothing, fcntl will fail anyway */
 }
 
-/* Create the lock file.  The lock file will be removed if we catch a signal
-   or when we exit.  The value of lock is tested to remove the race.  */
+/* Create the lock file.
+   The lock file will be removed if we catch a signal or when we exit. */
+/* The old code here used flock on a lock file /etc/mtab~ and deleted
+   this lock file afterwards. However, as rgooch remarks, that has a
+   race: a second mount may be waiting on the lock and proceed as
+   soon as the lock file is deleted by the first mount, and immediately
+   afterwards a third mount comes, creates a new /etc/mtab~, applies
+   flock to that, and also proceeds, so that the second and third mount
+   now both are scribbling in /etc/mtab.
+   The new code uses a link() instead of a creat(), where we proceed
+   only if it was us that created the lock, and hence we always have
+   to delete the lock afterwards. Now the use of flock() is in principle
+   superfluous, but avoids an arbitrary sleep(). */
+
+/* Where does the link point to? Obvious choices are mtab and mtab~~.
+   Maybe the latter is preferable. */
+#define MOUNTLOCK_LINKTARGET   MOUNTED_LOCK "~"
+
 void
 lock_mtab (void) {
-     int sig = 0;
-     struct sigaction sa;
-     struct flock flock;
-
-     /* If this is the first time, ensure that the lock will be removed.  */
-     if (lock < 0) {
-         struct stat st;
-         sa.sa_handler = handler;
-         sa.sa_flags = 0;
-         sigfillset (&sa.sa_mask);
-  
-         while (sigismember (&sa.sa_mask, ++sig) != -1 && sig != SIGCHLD) {
-              if (sig == SIGALRM)
-                   sa.sa_handler = setlkw_timeout;
-              else
-                   sa.sa_handler = handler;
-              sigaction (sig, &sa, (struct sigaction *) 0);
-         }
+       int tries = 3;
 
-         /* This stat is performed so we know when not to be overly eager
-            when cleaning up after signals. The window between stat and
-            open is not significant. */
-         if (lstat (MOUNTED_LOCK, &st) < 0 && errno == ENOENT)
-              old_lockfile = 0;
-
-         lock = open (MOUNTED_LOCK, O_WRONLY|O_CREAT, 0);
-         if (lock < 0) {
-              die (EX_FILEIO, "can't create lock file %s: %s "
-                      "(use -n flag to override)",
-                   MOUNTED_LOCK, strerror (errno));
-         }
+       if (!signals_have_been_setup) {
+               int sig = 0;
+               struct sigaction sa;
 
-         flock.l_type = F_WRLCK;
-         flock.l_whence = SEEK_SET;
-         flock.l_start = 0;
-         flock.l_len = 0;
-
-         alarm(LOCK_BUSY);
-         if (fcntl (lock, F_SETLKW, &flock) < 0) {
-              close (lock);
-              /* The file should not be removed */
-              lock = -1;
-              die (EX_FILEIO, "can't lock lock file %s: %s",
-                   MOUNTED_LOCK,
-                   errno == EINTR ? "timed out" : strerror (errno));
-         }
-         /* We have now access to the lock, and it can always be removed */
-         old_lockfile = 0;
-     }
+               sa.sa_handler = handler;
+               sa.sa_flags = 0;
+               sigfillset (&sa.sa_mask);
+  
+               while (sigismember (&sa.sa_mask, ++sig) != -1
+                      && sig != SIGCHLD) {
+                       if (sig == SIGALRM)
+                               sa.sa_handler = setlkw_timeout;
+                       else
+                               sa.sa_handler = handler;
+                       sigaction (sig, &sa, (struct sigaction *) 0);
+               }
+               signals_have_been_setup = 1;
+       }
+
+       /* Repeat until it was us who made the link */
+       while (!we_created_lockfile) {
+               struct flock flock;
+               int errsv, fd, i, j;
+
+               i = open (MOUNTLOCK_LINKTARGET, O_WRONLY|O_CREAT, 0);
+               if (i < 0) {
+                       /* MOUNTLOCK_LINKTARGET does not exist (as a file)
+                          and we cannot create it. Read-only filesystem?
+                          Too many files open in the system? Filesystem full? */
+                       die (EX_FILEIO, "can't create lock file %s: %s "
+                            "(use -n flag to override)",
+                            MOUNTLOCK_LINKTARGET, strerror (errno));
+               }
+               close(i);
+
+               j = link(MOUNTLOCK_LINKTARGET, MOUNTED_LOCK);
+               errsv = errno;
+
+               (void) unlink(MOUNTLOCK_LINKTARGET);
+
+               if (j < 0 && errsv != EEXIST) {
+                       die (EX_FILEIO, "can't link lock file %s: %s "
+                            "(use -n flag to override)",
+                            MOUNTED_LOCK, strerror (errsv));
+               }
+
+               fd = open (MOUNTED_LOCK, O_WRONLY);
+
+               if (fd < 0) {
+                       /* Strange... Maybe the file was just deleted? */
+                       if (errno == ENOENT && tries-- > 0)
+                               continue;
+                       die (EX_FILEIO, "can't open lock file %s: %s "
+                            "(use -n flag to override)",
+                            MOUNTED_LOCK, strerror (errno));
+               }
+
+               flock.l_type = F_WRLCK;
+               flock.l_whence = SEEK_SET;
+               flock.l_start = 0;
+               flock.l_len = 0;
+
+               if (j == 0) {
+                       /* We made the link. Now claim the lock. */
+                       if (fcntl (fd, F_SETLK, &flock) == -1) {
+                               if (verbose)
+                                   printf("Can't lock lock file %s: %s\n",
+                                          MOUNTED_LOCK, strerror (errno));
+                               /* proceed anyway */
+                       }
+                       we_created_lockfile = 1;
+               } else {
+                       /* Someone else made the link. Wait. */
+                       alarm(LOCK_TIMEOUT);
+                       if (fcntl (fd, F_SETLKW, &flock) == -1) {
+                               die (EX_FILEIO, "can't lock lock file %s: %s",
+                                    MOUNTED_LOCK, (errno == EINTR) ?
+                                    "timed out" : strerror (errno));
+                       }
+                       alarm(0);
+                       /* Maybe limit the number of iterations? */
+               }
+
+               close(fd);
+       }
 }
 
 /* Remove lock file.  */
 void
 unlock_mtab (void) {
-     if (lock != -1) {
-         close (lock);
-         if (!old_lockfile)
-              unlink (MOUNTED_LOCK);
-     }
+       if (we_created_lockfile) {
+               unlink (MOUNTED_LOCK);
+               we_created_lockfile = 0;
+       }
 }
 
 /*
@@ -322,27 +422,32 @@ update_mtab (const char *dir, struct mntent *instead) {
      struct mntent *next;
      struct mntent remnt;
      int added = 0;
-     FILE *fp, *ftmp;
+     mntFILE *mfp, *mftmp;
 
      if (mtab_does_not_exist() || mtab_is_a_symlink())
          return;
 
      lock_mtab();
 
-     if ((fp = setmntent(MOUNTED, "r")) == NULL) {
+     mfp = my_setmntent(MOUNTED, "r");
+     if (mfp == NULL || mfp->mntent_fp == NULL) {
          error ("cannot open %s (%s) - mtab not updated",
                 MOUNTED, strerror (errno));
          goto leave;
      }
 
-     if ((ftmp = setmntent (MOUNTED_TEMP, "w")) == NULL) {
+     mftmp = my_setmntent (MOUNTED_TEMP, "w");
+     if (mftmp == NULL || mfp->mntent_fp == NULL) {
          error ("can't open %s (%s) - mtab not updated",
                 MOUNTED_TEMP, strerror (errno));
          goto leave;
      }
   
-     while ((mnt = getmntent (fp))) {
-         if (streq (mnt->mnt_dir, dir)) {
+     while ((mnt = my_getmntent (mfp))) {
+         if (streq (mnt->mnt_dir, dir)
+             /* Matthew Wilcox <willy@odie.barnet.ac.uk> */
+             || (instead && instead->mnt_fsname &&
+                 (streq (mnt->mnt_fsname, instead->mnt_fsname)))) {
               added++;
               if (instead) {   /* a remount */
                    remnt = *instead;
@@ -362,19 +467,19 @@ update_mtab (const char *dir, struct mntent *instead) {
                    next = NULL;
          } else
               next = mnt;
-         if (next && addmntent(ftmp, next) == 1)
+         if (next && my_addmntent(mftmp, next) == 1)
               die (EX_FILEIO, "error writing %s: %s",
                    MOUNTED_TEMP, strerror (errno));
      }
-     if (instead && !added && addmntent(ftmp, instead) == 1)
+     if (instead && !added && my_addmntent(mftmp, instead) == 1)
          die (EX_FILEIO, "error writing %s: %s",
               MOUNTED_TEMP, strerror (errno));
 
-     endmntent (fp);
-     if (fchmod (fileno (ftmp), S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) < 0)
+     my_endmntent (mfp);
+     if (fchmod (fileno (mftmp->mntent_fp), S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) < 0)
          fprintf(stderr, "error changing mode of %s: %s\n", MOUNTED_TEMP,
                  strerror (errno));
-     endmntent (ftmp);
+     my_endmntent (mftmp);
 
      if (rename (MOUNTED_TEMP, MOUNTED) < 0)
          fprintf(stderr, "can't rename %s to %s: %s\n", MOUNTED_TEMP, MOUNTED,
index f22f2e7cb3c42a2ea2f19429bfc7948d19022597..e0b3895c2fea1c413e7fc20f4c11c5eae9275c59 100644 (file)
@@ -1,7 +1,7 @@
 #define _PATH_FSTAB    "/etc/fstab"
 #define MOUNTED_LOCK   "/etc/mtab~"
 #define MOUNTED_TEMP   "/etc/mtab.tmp"
-#define LOCK_BUSY      10
+#define LOCK_TIMEOUT   10
 
 int mtab_is_writable(void);
 int mtab_does_not_exist(void);
@@ -18,10 +18,13 @@ struct mntentchn {
 struct mntentchn *mtab_head (void);
 struct mntentchn *getmntfile (const char *name);
 struct mntentchn *getmntoptfile (const char *file);
+struct mntentchn *getmntfilesbackward (const char *file, struct mntentchn *mc);
 
 struct mntentchn *fstab_head (void);
 struct mntentchn *getfsfile (const char *file);
 struct mntentchn *getfsspec (const char *spec);
+struct mntentchn *getfsuuidspec (const char *uuid);
+struct mntentchn *getfsvolspec (const char *label);
 
 #include <mntent.h>
 void lock_mtab (void);
diff --git a/mount/getusername.c b/mount/getusername.c
new file mode 100644 (file)
index 0000000..9835768
--- /dev/null
@@ -0,0 +1,14 @@
+#include <unistd.h>
+#include <pwd.h>
+#include <sys/types.h>
+#include "getusername.h"
+
+char *
+getusername() {
+       char *user = 0;
+       struct passwd *pw = getpwuid(getuid());
+
+       if (pw)
+               user = pw->pw_name;
+       return user;
+}
diff --git a/mount/getusername.h b/mount/getusername.h
new file mode 100644 (file)
index 0000000..808ac9b
--- /dev/null
@@ -0,0 +1 @@
+extern char *getusername(void);
index 4e73c3b04bf9092b3d83229e219e772f23fb5621..bdc548c216115aca4696b9546d9ee0292a6de122 100644 (file)
@@ -4,7 +4,13 @@
    in case no filesystem type was given. */
 
 #ifndef BLKGETSIZE
+#ifndef _IO
+/* pre-1.3.45 */
 #define BLKGETSIZE 0x1260                 /* return device size */
+#else
+/* same on i386, m68k, arm; different on alpha, mips, sparc, ppc */
+#define BLKGETSIZE _IO(0x12,96)
+#endif
 #endif
 
 #define MINIX_SUPER_MAGIC   0x137F         /* original minix fs */
@@ -43,8 +49,11 @@ struct ext_super_block {
 #define EXT2_PRE_02B_MAGIC  0xEF51
 #define EXT2_SUPER_MAGIC    0xEF53
 struct ext2_super_block {
-       u_char   s_dummy[56];
+       u_char   s_dummy1[56];
        u_char   s_magic[2];
+       u_char   s_dummy2[46];
+       u_char   s_uuid[16];
+       u_char   s_volume_name[16];
 };
 #define ext2magic(s)   ((uint) s.s_magic[0] + (((uint) s.s_magic[1]) << 8))
 
@@ -57,3 +66,13 @@ struct xiafs_super_block {
 #define xiafsmagic(s)  ((uint) s.s_magic[0] + (((uint) s.s_magic[1]) << 8) + \
                        (((uint) s.s_magic[2]) << 16) + \
                        (((uint) s.s_magic[3]) << 24))
+
+/* From jj@sunsite.ms.mff.cuni.cz Mon Mar 23 15:19:05 1998 */
+#define UFS_SUPER_MAGIC 0x00011954
+struct ufs_super_block {
+    u_char     s_dummy[0x55c];
+    u_char     s_magic[4];
+};
+#define ufsmagic(s)    ((uint) s.s_magic[0] + (((uint) s.s_magic[1]) << 8) + \
+                        (((uint) s.s_magic[2]) << 16) + \
+                        (((uint) s.s_magic[3]) << 24))
index 8f9dbe52b749e15d60d511043dcd7b98279869bc..8a75a9aef8d114f9b38e78d26ff35d7c4e28d6d5 100644 (file)
@@ -202,12 +202,12 @@ int main(int argc, char **argv)
        if ((delete && (argc != optind+1 || encryption || offset)) ||
            (!delete && (argc < optind+1 || argc > optind+2)))
                usage();
-       if (argc == optind+1)
+       if (argc == optind+1) {
                if (delete)
                        del_loop(argv[optind]);
                else
                        show_loop(argv[optind]);
-       else {
+       else {
                if (offset && sscanf(offset,"%d",&off) != 1)
                        usage();
                set_loop(argv[optind],argv[optind+1],off,encryption,&ro);
index 9351b57e0f67ccc9fabe47487e41b55a0b07eec1..0f8a1a6170caa57e0dcf60fb6517dad9433ed700 100644 (file)
@@ -8,11 +8,12 @@ rm -f loop.h
 # Since 1.3.79 there is an include file <asm/posix_types.h>
 # that defines __kernel_dev_t.
 # (The file itself appeared in 1.3.78, but there it defined __dev_t.)
-# If it exists, we use it.  Otherwise we guess that __kernel_dev_t
+# If it exists, we use it, or, rather, <linux/posix_types.h> which
+# avoids namespace pollution.  Otherwise we guess that __kernel_dev_t
 # is an unsigned short (which is true on i386, but false on alpha).
 
-if [ -f /usr/include/asm/posix_types.h ]; then
-   echo '#include <asm/posix_types.h>' >> loop.h
+if [ -f /usr/include/linux/posix_types.h ]; then
+   echo '#include <linux/posix_types.h>' >> loop.h
    echo '#define dev_t __kernel_dev_t' >> loop.h
 else
    echo '#define dev_t unsigned short' >> loop.h
diff --git a/mount/mntent.c b/mount/mntent.c
new file mode 100644 (file)
index 0000000..0be20e8
--- /dev/null
@@ -0,0 +1,214 @@
+/* Private version of the libc *mntent() routines. */
+/* Note slightly different prototypes. */
+
+#include <stdio.h>
+#include <string.h>            /* for index */
+#include <ctype.h>             /* for isdigit */
+#include "mntent.h"
+#include "sundries.h"          /* for xmalloc */
+
+/* Unfortunately the classical Unix /etc/mtab and /etc/fstab
+   do not handle directory names containing spaces.
+   Here we mangle them, replacing a space by \040.
+   What do other Unices do? */
+
+static unsigned char need_escaping[] = { ' ', '\t', '\n', '\\' };
+
+static char *
+mangle(unsigned char *s) {
+       char *ss, *sp;
+       int n;
+
+       n = strlen(s);
+       ss = sp = xmalloc(4*n+1);
+       while(1) {
+               for (n = 0; n < sizeof(need_escaping); n++) {
+                       if (*s == need_escaping[n]) {
+                               *sp++ = '\\';
+                               *sp++ = '0' + ((*s & 0300) >> 6);
+                               *sp++ = '0' + ((*s & 070) >> 3);
+                               *sp++ = '0' + (*s & 07);
+                               goto next;
+                       }
+               }
+               *sp++ = *s;
+               if (*s == 0)
+                       break;
+       next:
+               s++;
+       }
+       return ss;
+}
+
+static int
+is_space_or_tab (char c) {
+       return (c == ' ' || c == '\t');
+}
+
+static char *
+skip_spaces(char *s) {
+       while (is_space_or_tab(*s))
+               s++;
+       return s;
+}
+
+static char *
+skip_nonspaces(char *s) {
+       while (*s && !is_space_or_tab(*s))
+               s++;
+       return s;
+}
+
+#define isoctal(a) (((a) & ~7) == '0')
+
+/* returns malloced pointer - no more strdup required */
+static char *
+unmangle(char *s) {
+       char *ret, *ss, *sp;
+
+       ss = skip_nonspaces(s);
+       ret = sp = xmalloc(ss-s+1);
+       while(s != ss) {
+               if (*s == '\\' && isoctal(s[1]) && isoctal(s[2]) && isoctal(s[3])) {
+                       *sp++ = 64*(s[1] & 7) + 8*(s[2] & 7) + (s[3] & 7);
+                       s += 4;
+               } else
+                       *sp++ = *s++;
+       }
+       *sp = 0;
+       return ret;
+}
+
+/*
+ * 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
+ * returns 0.
+ * (On the other hand, mangling and unmangling is meaningless
+ *  for /proc/mounttab.)
+ */
+
+mntFILE *
+my_setmntent (const char *file, char *mode) {
+       mntFILE *mfp = xmalloc(sizeof(*mfp));
+
+       mfp->mntent_fp = fopen (file, mode);
+       mfp->mntent_file = xstrdup(file);
+       mfp->mntent_errs = (mfp->mntent_fp == NULL);
+       mfp->mntent_softerrs = 0;
+       mfp->mntent_lineno = 0;
+       return mfp;
+}
+
+void
+my_endmntent (mntFILE *mfp) {
+       if (mfp) {
+               if (mfp->mntent_fp)
+                       fclose(mfp->mntent_fp);
+               if (mfp->mntent_file)
+                       free(mfp->mntent_file);
+               free(mfp);
+       }
+}
+
+
+int
+my_addmntent (mntFILE *mfp, struct mntent *mnt) {
+       char *m1, *m2, *m3, *m4;
+       int res;
+
+       if (fseek (mfp->mntent_fp, 0, SEEK_END))
+               return 1;                       /* failure */
+
+       m1 = mangle(mnt->mnt_fsname);
+       m2 = mangle(mnt->mnt_dir);
+       m3 = mangle(mnt->mnt_type);
+       m4 = mangle(mnt->mnt_opts);
+
+       res = ((fprintf (mfp->mntent_fp, "%s %s %s %s %d %d\n",
+                        m1, m2, m3, m4, mnt->mnt_freq, mnt->mnt_passno)
+               < 0) ? 1 : 0);
+
+       free(m1);
+       free(m2);
+       free(m3);
+       free(m4);
+       return res;
+}
+
+/* Read the next entry from the file fp. Stop reading at an incorrect entry. */
+struct mntent *
+my_getmntent (mntFILE *mfp) {
+       static char buf[4096];
+       static struct mntent me;
+       char *s;
+
+ again:
+       if (mfp->mntent_errs || mfp->mntent_softerrs >= ERR_MAX)
+               return NULL;
+
+       /* read the next non-blank non-comment line */
+       do {
+               if (fgets (buf, sizeof(buf), mfp->mntent_fp) == NULL)
+                       return NULL;
+
+               mfp->mntent_lineno++;
+               s = index (buf, '\n');
+               if (s == NULL) {
+                       /* Missing final newline?  Otherwise extremely */
+                       /* long line - assume file was corrupted */
+                       if (feof(mfp->mntent_fp)) {
+                               fprintf(stderr, "[mntent]: warning: no final "
+                                       "newline at the end of %s\n",
+                                       mfp->mntent_file);
+                               s = index (buf, 0);
+                       } else {
+                               mfp->mntent_errs = 1;
+                               goto err;
+                       }
+               }
+               *s = 0;
+               s = skip_spaces(buf);
+       } while (*s == '\0' || *s == '#');
+
+       me.mnt_fsname = unmangle(s);
+       s = skip_nonspaces(s);
+       s = skip_spaces(s);
+       me.mnt_dir = unmangle(s);
+       s = skip_nonspaces(s);
+       s = skip_spaces(s);
+       me.mnt_type = unmangle(s);
+       s = skip_nonspaces(s);
+       s = skip_spaces(s);
+       me.mnt_opts = unmangle(s);
+       s = skip_nonspaces(s);
+       s = skip_spaces(s);
+
+       if(isdigit(*s)) {
+               me.mnt_freq = atoi(s);
+               while(isdigit(*s)) s++;
+       } else
+               me.mnt_freq = 0;
+       if(*s && !is_space_or_tab(*s))
+               goto err;
+
+       s = skip_spaces(s);
+       if(isdigit(*s)) {
+               me.mnt_passno = atoi(s);
+               while(isdigit(*s)) s++;
+       } else
+               me.mnt_passno = 0;
+       if(*s && !is_space_or_tab(*s))
+               goto err;
+
+       /* allow more stuff, e.g. comments, on this line */
+
+       return &me;
+
+ err:
+       mfp->mntent_softerrs++;
+       fprintf(stderr, "[mntent]: line %d in %s is bad%s\n",
+               mfp->mntent_lineno, mfp->mntent_file,
+               (mfp->mntent_errs || mfp->mntent_softerrs >= ERR_MAX) ?
+               "; rest of file ignored" : "");
+       goto again;
+}
diff --git a/mount/mntent.h b/mount/mntent.h
new file mode 100644 (file)
index 0000000..9b46ba0
--- /dev/null
@@ -0,0 +1,16 @@
+#include <mntent.h>            /* for struct mntent */
+
+#define ERR_MAX 5
+
+typedef struct mntFILEstruct {
+       FILE *mntent_fp;
+       char *mntent_file;
+       int mntent_lineno;
+       int mntent_errs;
+       int mntent_softerrs;
+} mntFILE;
+
+mntFILE *my_setmntent (const char *file, char *mode);
+void my_endmntent (mntFILE *mfp);
+int my_addmntent (mntFILE *mfp, struct mntent *mnt);
+struct mntent *my_getmntent (mntFILE *mfp);
index 097dee005bfd00ca0debe0dd219652afb9954393..633671b199c424cbd76e541720151c82ad6de943 100644 (file)
@@ -31,6 +31,8 @@
 .\" 970114, aeb: xiafs and ext are dead; romfs is new
 .\" 970623, aeb: -F option
 .\" 970914, reg: -s option
+.\" 981111, K.Garloff: /etc/filesystems
+.\" 990111, aeb: documented /sbin/mount.smbfs
 .\"
 .TH MOUNT 8 "14 September 1997" "Linux 2.0" "Linux Programmer's Manual"
 .SH NAME
@@ -111,6 +113,8 @@ but there are other possibilities. For example, in the case of an NFS mount,
 .I device
 may look like
 .IR knuth.cwi.nl:/dir .
+It is possible to indicate a block special device using its
+volume label or UUID (see the \-L and \-U options below).
 
 The file
 .I /etc/fstab
@@ -163,6 +167,14 @@ or
 .RE
 For more details, see
 .BR fstab (5).
+Only the user that mounted a filesystem can unmount it again.
+If any user should be able to unmount, then use
+.B users
+instead of
+.B user
+in the
+.I fstab
+line.
 
 The programs
 .B mount
@@ -265,16 +277,46 @@ Mount the file system read-only. A synonym is
 Mount the file system read/write. This is the default. A synonym is
 .BR "\-o rw" .
 .TP
+.BI \-L " label"
+Mount the partition that has the specified
+.IR label .
+.TP
+.BI \-U " uuid"
+Mount the partition that has the specified
+.IR uuid .
+These two options require the file
+.I /proc/partitions
+(present since Linux 2.1.116) to exist.
+.TP
 .BI \-t " vfstype"
 The argument following the
 .B \-t
 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 ", " ext ", " ext2 ", " xiafs ", " hpfs ,
-.IR msdos ", " umsdos ", " vfat ,
-.IR proc ", " nfs ", " iso9660 ", " smbfs ", " ncpfs ,
-.IR affs ", " ufs ", " romfs ,
+.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 coda ,
+.IR hfs ,
+.IR hpfs ,
+.IR ntfs ,
+.IR qnx4 ,
+.IR romfs ,
+.IR ufs ,
 .IR sysv ", " xenix ", " coherent .
 Note that the last three are equivalent and that
 .I xenix
@@ -288,6 +330,23 @@ and
 .I xiafs
 do not exist anymore.
 
+For most types all the
+.B mount
+program has to do is issue a simple
+.IR mount (2)
+system call, and no detailed knowledge of the filesystem type is required.
+For a few types however (like nfs, smbfs, ncpfs) ad hoc code is
+necessary. The nfs ad hoc code is built in, but smbfs and ncpfs
+have a separate mount program. In order to make it possible to
+treat all types in a uniform way, mount will execute the program
+.I /sbin/mount.TYPE
+(if that exists) when called with type smb or ncp.
+Since various versions of the
+.I smbmount
+program have different calling conventions,
+.I /sbin/mount.smb
+may have to be a shell script that sets up the desired call.
+
 The type
 .I iso9660
 is the default.  If no
@@ -297,9 +356,11 @@ option is given, or if the
 type is specified, the superblock is probed for the filesystem type
 .RI ( minix ", " ext ", " ext2 ", " xiafs ", " iso9660 ", " romfs
 are supported).
-If this probe fails and
-.I /proc/filesystems
-exists, then all of the filesystems listed there will be tried,
+If this probe fails, mount will try to read the file
+.IR /etc/filesystems ,
+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.,
 .I proc
 and
@@ -308,6 +369,10 @@ and
 Note that the
 .B auto
 type may be useful for user-mounted floppies.
+Creating a file
+.I /etc/filesystems
+can be useful to change the probe order (e.g., to try vfat before msdos)
+or if you use a kernel module autoloader.
 Warning: the probing uses a heuristic (the presence of appropriate `magic'),
 and could recognize the wrong filesystem type.
 
@@ -381,7 +446,8 @@ binaries for architectures other than its own.
 .TP
 .B nosuid
 Do not allow set-user-identifier or set-group-identifier bits to take
-effect.
+effect. (This seems safe, but is in fact rather unsafe if you have
+suidperl(1) installed.)
 .TP
 .B nouser
 Forbid an ordinary (i.e., non-root) user to mount the file system.
@@ -1000,4 +1066,4 @@ for the
 .SH HISTORY
 A
 .B mount
-command appeared in Version 6 AT&T UNIX.
+command existed in Version 5 AT&T UNIX.
index 19c5076406e5e41c940a9f33107a36ba49e4912c..5ee247daa5d28f7d18784155c08082524e9f9891 100644 (file)
@@ -2,12 +2,6 @@
  * A mount(8) for Linux 0.99.
  * mount.c,v 1.1.1.1 1993/11/18 08:40:51 jrs Exp
  *
- * Thu Jul 14 07:32:40 1994: faith@cs.unc.edu added changes from Adam
- * J. Richter (adam@adam.yggdrasil.com) so that /proc/filesystems is used
- * if no -t option is given.  I modified his patches so that, if
- * /proc/filesystems is not available, the behavior of mount is the same as
- * it was previously.
- *
  * Wed Sep 14 22:43:00 1994: Mitchum DSouza
  * (mitch@mrc-applied-psychology.cambridge.ac.uk) added support for mounting
  * the "loop" device.
  * Wed Sep 14 22:55:10 1994: Sander van Malssen (svm@kozmix.hacktic.nl)
  * added support for remounting readonly file systems readonly.
  *
- * Wed Feb 8 09:23:18 1995: Mike Grupenhoff <kashmir@umiacs.UMD.EDU> added
- * a probe of the superblock for the type before /proc/filesystems is
- * checked.
- *
  * Wed Feb  8 12:27:00 1995: Andries.Brouwer@cwi.nl fixed up error messages.
  * Sat Jun  3 20:44:38 1995: Patches from Andries.Brouwer@cwi.nl applied.
  * Tue Sep 26 22:38:20 1995: aeb@cwi.nl, many changes
  * Fri Feb 23 13:47:00 1996: aeb@cwi.nl, loop device related changes
  *
- * Fri Apr  5 01:13:33 1996: quinlan@bucknell.edu, fixed up iso9660 autodetect
- *
  * Since then, many changes - aeb.
  *
  * Wed Oct  1 23:55:28 1997: Dick Streefland <dick_streefland@tasking.com>
  * Implemented the "bg", "fg" and "retry" mount options for NFS.
+ *
+ * Tue Aug  4 15:54:31 1998: aeb@cwi.nl:
+ * Open fd 0,1,2 so that printf's do not clobber /etc/mtab or so.
+ * Mangle filenames with embedded spaces. Add ufsmagic. Add locking.
+ * Avoid unnecessary error messages about /proc.
+ * Improve support for noncanonical names in /etc/fstab.
+ * Add support for volume labels and UUIDs.
  */
 
 #include <unistd.h>
 
 #include "mount_constants.h"
 #include "sundries.h"
+#include "mntent.h"
 #include "fstab.h"
 #include "lomount.h"
 #include "loop.h"
-#include "linux_fs.h"
-
-#define PROC_FILESYSTEMS       "/proc/filesystems"
-#define SIZE(a) (sizeof(a)/sizeof(a[0]))
+#include "linux_fs.h"          /* for BLKGETSIZE */
+#include "mount_guess_fstype.h"
+#include "mount_by_label.h"
+#include "getusername.h"
 
 #define DO_PS_FIDDLING
 
 #ifdef DO_PS_FIDDLING
-#define PROC_NAME              "mount: "
-static int argc0;
-static char** argv0;
-static char** envp0;
-extern char** environ;
+#include "setproctitle.h"
 #endif
 
 /* True for fake mount (-f).  */
@@ -105,14 +97,15 @@ struct opt_map
 /* We can use the high-order 16 bits, since the mount call
    has MS_MGC_VAL there. */
 #define MS_NOAUTO      0x80000000
-#define MS_USER                0x40000000
+#define MS_USERS       0x40000000
+#define MS_USER                0x20000000
 #define MS_LOOP                0x00010000
 
 /* Options that we keep the mount system call from seeing.  */
-#define MS_NOSYS       (MS_NOAUTO|MS_USER|MS_LOOP)
+#define MS_NOSYS       (MS_NOAUTO|MS_USERS|MS_USER|MS_LOOP)
 
 /* Options that we keep from appearing in the options field in the mtab.  */
-#define MS_NOMTAB      (MS_REMOUNT|MS_NOAUTO|MS_USER)
+#define MS_NOMTAB      (MS_REMOUNT|MS_NOAUTO|MS_USERS|MS_USER)
 
 /* OPTIONS that we make ordinary users have by default.  */
 #define MS_SECURE      (MS_NOEXEC|MS_NOSUID|MS_NODEV)
@@ -132,6 +125,8 @@ const struct opt_map opt_map[] = {
   { "remount",  0, 0, MS_REMOUNT},      /* Alter flags of mounted FS */
   { "auto",    0, 1, MS_NOAUTO },      /* Can be mounted using -a */
   { "noauto",  0, 0, MS_NOAUTO },      /* Can  only be mounted explicitly */
+  { "users",   0, 0, MS_USERS  },      /* Allow ordinary user to mount */
+  { "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 */
   /* add new options here */
@@ -159,7 +154,7 @@ const struct opt_map opt_map[] = {
   { NULL,      0, 0, 0         }
 };
 
-char *opt_loopdev, *opt_vfstype, *opt_offset, *opt_encryption;
+static char *opt_loopdev, *opt_vfstype, *opt_offset, *opt_encryption;
 
 struct string_opt_map {
   char *tag;
@@ -233,13 +228,12 @@ parse_opt (const char *opt, int *mask, char *extra_opts)
   const struct opt_map *om;
 
   for (om = opt_map; om->opt != NULL; om++)
-    if (streq (opt, om->opt))
-      {
+      if (streq (opt, om->opt)) {
        if (om->inv)
          *mask &= ~om->mask;
        else
          *mask |= om->mask;
-       if (om->mask == MS_USER)
+       if (om->mask == MS_USER || om->mask == MS_USERS)
          *mask |= MS_SECURE;
 #ifdef MS_SILENT
         if (om->mask == MS_SILENT && om->inv)  {
@@ -284,8 +278,7 @@ parse_opts (char *opts, int *flags, char **extra_opts)
 
 /* Try to build a canonical options string.  */
 static char *
-fix_opts_string (int flags, char *extra_opts)
-{
+fix_opts_string (int flags, const char *extra_opts, const char *user) {
   const struct opt_map *om;
   const struct string_opt_map *m;
   char *new_opts;
@@ -306,167 +299,14 @@ fix_opts_string (int flags, char *extra_opts)
   if (extra_opts && *extra_opts) {
       new_opts = xstrconcat3(new_opts, ",", extra_opts);
   }
+  if (user) {
+      new_opts = xstrconcat3(new_opts, ",user=", user);
+  }
   return new_opts;
 }
 
-/* Most file system types can be recognized by a `magic' number
-   in the superblock.  Note that the order of the tests is
-   significant: by coincidence a filesystem can have the
-   magic numbers for several file system types simultaneously.
-   For example, the romfs magic lives in the 1st sector;
-   xiafs does not touch the 1st sector and has its magic in
-   the 2nd sector; ext2 does not touch the first two sectors. */
-
-static inline unsigned short
-swapped(unsigned short a) {
-     return (a>>8) | (a<<8);
-}
-
-/*
-    char *fstype(const char *device);
-
-    Probes the device and attempts to determine the type of filesystem
-    contained within.
-
-    Original routine by <jmorriso@bogomips.ww.ubc.ca>; made into a function
-    for mount(8) by Mike Grupenhoff <kashmir@umiacs.umd.edu>.
-    Read the superblock only once - aeb
-    Added a test for iso9660 - aeb
-    Added a test for high sierra (iso9660) - quinlan@bucknell.edu
-    Corrected the test for xiafs - aeb
-    Added romfs - aeb
-
-    Currently supports: minix, ext, ext2, xiafs, iso9660, romfs
-*/
-char *magic_known[] = { "minix", "ext", "ext2", "xiafs", "iso9660", "romfs" };
-
 static int
-tested(const char *device) {
-    char **m;
-
-    for (m = magic_known; m - magic_known < SIZE(magic_known); m++)
-        if (!strcmp(*m, device))
-           return 1;
-    return 0;
-}
-
-static char *
-fstype(const char *device)
-{
-    int fd;
-    char *type = NULL;
-    union {
-       struct minix_super_block ms;
-       struct ext_super_block es;
-       struct ext2_super_block e2s;
-    } sb;
-    union {
-       struct xiafs_super_block xiasb;
-       char romfs_magic[8];
-    } xsb;
-    union {
-       struct iso_volume_descriptor iso;
-       struct hs_volume_descriptor hs;
-    } isosb;
-    struct stat statbuf;
-
-    /* opening and reading an arbitrary unknown path can have
-       undesired side effects - first check that `device' refers
-       to a block device */
-    if (stat (device, &statbuf) || !S_ISBLK(statbuf.st_mode))
-      return 0;
-
-    fd = open(device, O_RDONLY);
-    if (fd < 0)
-      return 0;
-
-    if (lseek(fd, 1024, SEEK_SET) != 1024
-       || read(fd, (char *) &sb, sizeof(sb)) != sizeof(sb))
-        goto io_error;
-
-    if (ext2magic(sb.e2s) == EXT2_SUPER_MAGIC
-       || ext2magic(sb.e2s) == EXT2_PRE_02B_MAGIC
-       || ext2magic(sb.e2s) == swapped(EXT2_SUPER_MAGIC))
-        type = "ext2";
-
-    else if (minixmagic(sb.ms) == MINIX_SUPER_MAGIC
-            || minixmagic(sb.ms) == MINIX_SUPER_MAGIC2)
-        type = "minix";
-
-    else if (extmagic(sb.es) == EXT_SUPER_MAGIC)
-        type = "ext";
-
-    if (!type) {
-        if (lseek(fd, 0, SEEK_SET) != 0
-            || read(fd, (char *) &xsb, sizeof(xsb)) != sizeof(xsb))
-             goto io_error;
-
-        if (xiafsmagic(xsb.xiasb) == _XIAFS_SUPER_MAGIC)
-             type = "xiafs";
-        else if(!strncmp(xsb.romfs_magic, "-rom1fs-", 8))
-             type = "romfs";
-    }
-
-    if (!type) {
-        if (lseek(fd, 0x8000, SEEK_SET) != 0x8000
-            || read(fd, (char *) &isosb, sizeof(isosb)) != sizeof(isosb))
-             goto io_error;
-
-        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";
-    }
-
-    close (fd);
-    return(type);
-
-io_error:
-    perror(device);
-    close(fd);
-    return 0;
-}
-
-FILE *procfs;
-
-static void
-procclose(void) {
-    if (procfs)
-        fclose (procfs);
-    procfs = 0;
-}
-
-static int
-procopen(void) {
-    return ((procfs = fopen(PROC_FILESYSTEMS, "r")) != NULL);
-}
-
-static char *
-procnext(void) {
-   char line[100];
-   static char fsname[50];
-
-   while (fgets(line, sizeof(line), procfs)) {
-      if (sscanf (line, "nodev %[^\n]\n", fsname) == 1) continue;
-      if (sscanf (line, " %[^ \n]\n", fsname) != 1) continue;
-      return fsname;
-   }
-   return 0;
-}
-
-static int
-is_in_proc(char *type) {
-    char *fsname;
-
-    if (procopen()) {
-       while ((fsname = procnext()) != NULL)
-         if (!strcmp(fsname, type))
-           return 1;
-    }
-    return 0;
-}
-
-static int
-already (char *spec, char *node) {
+already (const char *spec, const char *node) {
     struct mntentchn *mc;
     int ret = 1;
 
@@ -488,11 +328,12 @@ create_mtab (void) {
   struct mntent mnt;
   int flags;
   char *extra_opts;
-  FILE *fp;
+  mntFILE *mfp;
 
   lock_mtab();
 
-  if ((fp = setmntent (MOUNTED, "a+")) == NULL)
+  mfp = my_setmntent (MOUNTED, "a+");
+  if (mfp == NULL || mfp->mntent_fp == NULL)
     die (EX_FILEIO, "mount: can't open %s for writing: %s",
         MOUNTED, strerror (errno));
 
@@ -502,18 +343,18 @@ create_mtab (void) {
       mnt.mnt_dir = "/";
       mnt.mnt_fsname = canonicalize (fstab->mnt_fsname);
       mnt.mnt_type = fstab->mnt_type;
-      mnt.mnt_opts = fix_opts_string (flags, extra_opts);
+      mnt.mnt_opts = fix_opts_string (flags, extra_opts, NULL);
       mnt.mnt_freq = mnt.mnt_passno = 0;
 
-      if (addmntent (fp, &mnt) == 1)
+      if (my_addmntent (mfp, &mnt) == 1)
        die (EX_FILEIO, "mount: error writing %s: %s",
             MOUNTED, strerror (errno));
   }
-  if (fchmod (fileno (fp), S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) < 0)
+  if (fchmod (fileno (mfp->mntent_fp), S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) < 0)
     if (errno != EROFS)
       die (EX_FILEIO, "mount: error changing mode of %s: %s",
           MOUNTED, strerror (errno));
-  endmntent (fp);
+  my_endmntent (mfp);
 
   unlock_mtab();
 }
@@ -522,8 +363,9 @@ create_mtab (void) {
 static int mountcount = 0;
 
 static int
-mount5 (char *special, char *dir, char *type, int flags, void *data) {
-     int ret = mount (special, dir, type, 0xC0ED0000 | (flags), data);
+mount5 (struct mountargs *args) {
+     int ret = mount (args->spec, args->node, args->type,
+                     MS_MGC_VAL | (args->flags), args->data);
      if (ret == 0)
          mountcount++;
      return ret;
@@ -534,46 +376,20 @@ mount5 (char *special, char *dir, char *type, int flags, void *data) {
  
 static int
 try_mount5 (char *spec, char *node, char **type, int flags, char *mount_opts) {
-   char *fsname;
+   struct mountargs args = { spec, node, NULL, flags & ~MS_NOSYS, mount_opts };
    
    if (*type && strcasecmp (*type, "auto") == 0)
       *type = NULL;
 
-   if (!*type && !(flags & MS_REMOUNT)) {
-      *type = fstype(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
-           printf ("       I will try all types mentioned in %s\n",
-                   PROC_FILESYSTEMS);
-      }
-   }
+   if (!*type && !(flags & MS_REMOUNT))
+      *type = guess_fstype_from_superblock(spec);
 
-   if (*type || (flags & MS_REMOUNT))
-      return mount5 (spec, node, *type, flags & ~MS_NOSYS, mount_opts);
-
-   if (!procopen())
-     return -1;
-   while ((fsname = procnext()) != NULL) {
-      if (tested (fsname))
-        continue;
-      if (mount5 (spec, node, fsname, flags & ~MS_NOSYS, mount_opts) == 0) {
-        *type = xstrdup(fsname);
-        procclose();
-        return 0;
-      } else if (errno != EINVAL) {
-         *type = "guess";
-        procclose();
-        return 1;
-      }
+   if (*type || (flags & MS_REMOUNT)) {
+      args.type = *type;
+      return mount5 (&args);
    }
-   procclose();
-   *type = NULL;
 
-   return -1;
+   return procfsloop(mount5, &args, type);
 }
 
 /*
@@ -584,9 +400,8 @@ try_mount5 (char *spec, char *node, char **type, int flags, char *mount_opts) {
  *     background.
  */
 static int
-try_mount_one (char *spec0, char *node0, char *type0, char *opts0,
-              int freq, int pass, int bg)
-{
+try_mount_one (const char *spec0, const char *node0, char *type0,
+              const char *opts0, int freq, int pass, int bg) {
   struct mntentchn mcn;
   struct mntent mnt;
   int mnt_err;
@@ -595,7 +410,9 @@ try_mount_one (char *spec0, char *node0, char *type0, char *opts0,
   char *mount_opts;            /* actually used on system call */
   static int added_ro = 0;
   int loop, looptype, offset;
-  char *spec, *node, *type, *opts, *loopdev, *loopfile;
+  const char *opts;
+  char *spec, *node, *type, *loopdev, *loopfile;
+  char *user = 0;
   struct stat statbuf;
 
   spec = xstrdup(spec0);
@@ -606,11 +423,15 @@ try_mount_one (char *spec0, char *node0, char *type0, char *opts0,
   parse_opts (xstrdup (opts), &flags, &extra_opts);
 
   /* root may allow certain types of mounts by ordinary users */
-  if (suid && !(flags & MS_USER)) {
-      if (already (spec, node))
-       die (EX_USAGE, "mount failed");
-      else
-        die (EX_USAGE, "mount: only root can mount %s on %s", spec, node);
+  if (suid) {
+      if (!(flags & (MS_USER | MS_USERS))) {
+          if (already (spec, node))
+           die (EX_USAGE, "mount failed");
+         else
+            die (EX_USAGE, "mount: only root can mount %s on %s", spec, node);
+      }
+      if (flags & MS_USER)
+         user = getusername();
   }
 
   /* quietly succeed for fstab entries that don't get mounted automatically */
@@ -661,8 +482,13 @@ try_mount_one (char *spec0, char *node0, char *type0, char *opts0,
       if (verbose)
        printf("mount: going to use the loop device %s\n", loopdev);
       offset = opt_offset ? strtoul(opt_offset, NULL, 0) : 0;
-      if (set_loop (loopdev, loopfile, offset, opt_encryption, &loopro))
+      if (set_loop (loopdev, loopfile, offset, opt_encryption, &loopro)) {
+       if (verbose)
+         printf("mount: failed setting up loop device\n");
        return EX_FAIL;
+      }
+      if (verbose > 1)
+       printf("mount: setup loop device successfully\n");
       spec = loopdev;
       if (loopro)
        flags |= MS_RDONLY;
@@ -686,7 +512,9 @@ try_mount_one (char *spec0, char *node0, char *type0, char *opts0,
    */
   if (type)
 #ifndef ALWAYS_STAT
-  if (streq (type, "smb") || streq (type, "ncp"))
+  if (streq (type, "smb") || streq (type, "ncp")
+      /* || streq (type, "smbfs") || streq (type, "ncpfs") */
+      )
 #else
   if (strlen (type) < 100)
 #endif
@@ -701,7 +529,7 @@ try_mount_one (char *spec0, char *node0, char *type0, char *opts0,
 
                 setuid(getuid());
                 setgid(getgid());
-                oo = fix_opts_string (flags, extra_opts);
+                oo = fix_opts_string (flags, extra_opts, NULL);
                 mountargs[i++] = mountprog;
                 mountargs[i++] = spec;
                 mountargs[i++] = node;
@@ -721,7 +549,7 @@ try_mount_one (char *spec0, char *node0, char *type0, char *opts0,
                 wait(&status);
                 return status;
            } else
-                error("cannot fork: %s", strerror(errno));
+                error("mount: cannot fork: %s", strerror(errno));
        }
   }
 
@@ -737,7 +565,8 @@ try_mount_one (char *spec0, char *node0, char *type0, char *opts0,
       mcn.mnt_fsname = mnt.mnt_fsname = canonicalize (loop ? loopfile : spec);
       mcn.mnt_dir = mnt.mnt_dir = canonicalize (node);
       mcn.mnt_type = mnt.mnt_type = type ? type : "unknown";
-      mcn.mnt_opts = mnt.mnt_opts = fix_opts_string (flags & ~MS_NOMTAB, extra_opts);
+      mcn.mnt_opts = mnt.mnt_opts = fix_opts_string (flags & ~MS_NOMTAB,
+                                                    extra_opts, user);
       mcn.nxt = 0;
       mnt.mnt_freq = freq;
       mnt.mnt_passno = pass;
@@ -751,16 +580,20 @@ try_mount_one (char *spec0, char *node0, char *type0, char *opts0,
          if (flags & MS_REMOUNT)
               update_mtab (mnt.mnt_dir, &mnt);
          else {
-              FILE *fp = setmntent(MOUNTED, "a+");
-              if (fp == NULL)
+              mntFILE *mfp;
+
+              lock_mtab();
+              mfp = my_setmntent(MOUNTED, "a+");
+              if (mfp == NULL || mfp->mntent_fp == NULL) {
                    error("mount: can't open %s: %s", MOUNTED,
                          strerror (errno));
-              else {
-                   if ((addmntent (fp, &mnt)) == 1)
+              else {
+                   if ((my_addmntent (mfp, &mnt)) == 1)
                         error("mount: error writing %s: %s", MOUNTED,
                               strerror (errno));
-                   endmntent(fp);
+                   my_endmntent(mfp);
               }
+              unlock_mtab();
          }
       }
 
@@ -794,6 +627,12 @@ try_mount_one (char *spec0, char *node0, char *type0, char *opts0,
     case EBUSY:
       if (flags & MS_REMOUNT) {
        error ("mount: %s is busy", node);
+      } else if (!strcmp(type, "proc") && !strcmp(node, "/proc")) {
+       /* heuristic: if /proc/version exists, then probably proc is mounted */
+       if (stat ("/proc/version", &statbuf))   /* proc mounted? */
+          error ("mount: %s is busy", node);   /* no */
+       else if(!all || verbose)                /* yes, don't mention it */
+          error ("mount: proc already mounted");
       } else {
        error ("mount: %s already mounted or %s busy", spec, node);
        already (spec, node);
@@ -826,7 +665,7 @@ try_mount_one (char *spec0, char *node0, char *type0, char *opts0,
               spec);
 
        if (stat (spec, &statbuf) == 0 && S_ISBLK(statbuf.st_mode)
-          && (fd = open(spec, O_RDONLY)) >= 0) {
+          && (fd = open(spec, O_RDONLY | O_NONBLOCK)) >= 0) {
          if(ioctl(fd, BLKGETSIZE, &size) == 0 && size <= 2)
          error ("       (aren't you trying to mount an extended partition,\n"
                 "       instead of some logical partition inside?)");
@@ -840,9 +679,9 @@ try_mount_one (char *spec0, char *node0, char *type0, char *opts0,
     case EIO:
       error ("mount: %s: can't read superblock", spec); break;
     case ENODEV:
-      if (is_in_proc(type) || !strcmp(type, "guess"))
+      if (is_in_procfs(type) || !strcmp(type, "guess"))
         error("mount: %s has wrong major or minor number", spec);
-      else if (procfs) {
+      else if (have_procfs()) {
        char *lowtype, *p;
        int u;
 
@@ -857,9 +696,9 @@ try_mount_one (char *spec0, char *node0, char *type0, char *opts0,
            u++;
          }
        }
-       if (u && is_in_proc(lowtype))
+       if (u && is_in_procfs(lowtype))
          error ("mount: probably you meant %s", lowtype);
-       else if (!strncmp(lowtype, "iso", 3) && is_in_proc("iso9660"))
+       else if (!strncmp(lowtype, "iso", 3) && is_in_procfs("iso9660"))
          error ("mount: maybe you meant iso9660 ?");
        free(lowtype);
       } else
@@ -893,8 +732,9 @@ try_mount_one (char *spec0, char *node0, char *type0, char *opts0,
             type = type0;
         }
          if (opts) {
-             opts = realloc(xstrdup(opts), strlen(opts)+4);
-             strcat(opts, ",ro");
+            char *opts1 = realloc(xstrdup(opts), strlen(opts)+4);
+             strcat(opts1, ",ro");
+            opts = opts1;
          } else
              opts = "ro";
         if (type && !strcmp(type, "guess"))
@@ -916,42 +756,56 @@ try_mount_one (char *spec0, char *node0, char *type0, char *opts0,
  *     identified in a "ps" listing.
  */
 static void
-set_proc_name (char *spec)
+set_proc_name (const char *spec)
 {
 #ifdef DO_PS_FIDDLING
-  int i, l;
-
-  /*
-   * Move the environment so we can reuse the memory.
-   * (Code borrowed from sendmail.)
-   * WARNING: ugly assumptions on memory layout here; if this ever causes
-   *          problems, #undef DO_PS_FIDDLING
-   */
-  for (i = 0; envp0[i] != NULL; i++)
-    continue;
-  environ = (char **) xmalloc(sizeof(char *) * (i + 1));
-  for (i = 0; envp0[i] != NULL; i++)
-    environ[i] = xstrdup(envp0[i]);
-  environ[i] = NULL;
-
-  if (i > 0)
-    l = envp0[i-1] + strlen(envp0[i-1]) - argv0[0];
-  else
-    l = argv0[argc0-1] + strlen(argv0[argc0-1]) - argv0[0];
-  if (l > sizeof(PROC_NAME)) {
-    strcpy(argv0[0], PROC_NAME);
-    strncpy(argv0[0] + sizeof(PROC_NAME) - 1, spec, l - sizeof(PROC_NAME) - 1);
-    argv0[1] = NULL;
-  }
+       setproctitle ("mount", spec);
 #endif
 }
 
+static char *
+subst_string(const char *s, const char *sub, int sublen, const char *repl) {
+       char *n;
+
+       n = (char *) xmalloc(strlen(s)-sublen+strlen(repl)+1);
+       strncpy (n, s, sub-s);
+       strcpy (n + (sub-s), repl);
+       strcat (n, sub+sublen);
+       return n;
+}
+
+static const char *
+usersubst(const char *opts) {
+       char *s, *w;
+       char id[40];
+
+       s = "uid=useruid";
+       if (opts && (w = strstr(opts, s)) != NULL) {
+               sprintf(id, "uid=%d", getuid());
+               opts = subst_string(opts, w, strlen(s), id);
+       }
+       s = "gid=usergid";
+       if (opts && (w = strstr(opts, s)) != NULL) {
+               sprintf(id, "gid=%d", getgid());
+               opts = subst_string(opts, w, strlen(s), id);
+       }
+       return opts;
+}
+               
+
+/*
+ * Return 0 for success (either mounted sth or -a and NOAUTO was given)
+ */
 static int
-mount_one (char *spec, char *node, char *type, char *opts, char *cmdlineopts,
-          int freq, int pass)
-{
+mount_one (const char *spec, const char *node, char *type, const char *opts,
+          char *cmdlineopts, int freq, int pass) {
   int status;
   int status2;
+  int specset = 0;
+  char *nspec;
+
+  /* Substitute values in opts, if required */
+  opts = usersubst(opts);
 
   /* Merge the fstab and command line options.  */
   if (opts == NULL)
@@ -959,6 +813,26 @@ mount_one (char *spec, char *node, char *type, char *opts, char *cmdlineopts,
   else if (cmdlineopts != NULL)
        opts = xstrconcat3(opts, ",", cmdlineopts);
 
+  if (!strncmp(spec, "UUID=", 5)) {
+      nspec = get_spec_by_uuid(spec+5);
+      specset = 1;
+  } else if (!strncmp(spec, "LABEL=", 6)) {
+      nspec = get_spec_by_volume_label(spec+6);
+      specset = 2;
+  } else
+      nspec = 0;               /* just for gcc */
+
+  if (specset) {
+      if (nspec) {
+         spec = nspec;
+         if (verbose)
+                 printf("mount: consider mounting %s by %s\n", spec,
+                        (specset==1) ? "UUID" : "label");
+      } else if(!all)
+          die (EX_USAGE, "mount: no such partition found");
+      /* if -a then we may be rescued by a noauto option */
+  }
+
   if (type == NULL) {
       if (strchr (spec, ':') != NULL) {
        type = "nfs";
@@ -1146,10 +1020,11 @@ static struct option longopts[] =
 };
 
 const char *usage_string = "\
-usage: mount [-hV]\n\
+Usage: mount [-hV]\n\
        mount -a [-nfFrsvw] [-t vfstypes]\n\
        mount [-nfrsvw] [-o options] special | node\n\
        mount [-nfrsvw] [-t vfstype] [-o options] special node\n\
+A special device can be indicated by  -L label  or  -U uuid .
 ";
 
 static void
@@ -1162,18 +1037,26 @@ usage (FILE *fp, int n)
 
 int
 main (int argc, char *argv[]) {
-  int c, result = 0;
-  char *options = NULL, *spec;
+  int c, result = 0, specseen;
+  char *options = NULL, *spec, *node;
+  char *volumelabel = NULL;
+  char *uuid = NULL;
   string_list types = NULL;
   struct mntentchn *mc;
+  int fd;
+
+  /* People report that a mount called from init without console
+     writes error messages to /etc/mtab
+     Let us try to avoid getting fd's 0,1,2 */
+  while((fd = open("/dev/null", O_RDWR)) == 0 || fd == 1 || fd == 2) ;
+  if (fd > 2)
+     close(fd);
 
 #ifdef DO_PS_FIDDLING
-  argc0 = argc;
-  argv0 = argv;
-  envp0 = environ;
+  initproctitle(argc, argv);
 #endif
 
-  while ((c = getopt_long (argc, argv, "afFhno:rsvVwt:", longopts, NULL))
+  while ((c = getopt_long (argc, argv, "afFhL:no:rsU:vVwt:", longopts, NULL))
         != EOF)
     switch (c) {
       case 'a':                        /* mount everything in fstab */
@@ -1188,6 +1071,9 @@ main (int argc, char *argv[]) {
       case 'h':                        /* help */
        usage (stdout, 0);
        break;
+      case 'L':
+       volumelabel = optarg;
+       break;
       case 'n':                        /* mount without writing in /etc/mtab */
        ++nomtab;
        break;
@@ -1207,6 +1093,9 @@ main (int argc, char *argv[]) {
       case 't':                        /* specify file system types */
        types = parse_list (optarg);
        break;
+      case 'U':
+       uuid = optarg;
+       break;
       case 'v':                        /* be chatty - very chatty if repeated */
        ++verbose;
        break;
@@ -1227,7 +1116,9 @@ main (int argc, char *argv[]) {
   argc -= optind;
   argv += optind;
 
-  if (argc == 0 && !all) {
+  specseen = (uuid || volumelabel) ? 1 : 0;    /* yes, .. i know */
+
+  if (argc+specseen == 0 && !all) {
       if (options)
        usage (stderr, EX_USAGE);
       return print_all (types);
@@ -1235,7 +1126,8 @@ main (int argc, char *argv[]) {
 
   if (getuid () != geteuid ()) {
       suid = 1;
-      if (types || options || readwrite || nomtab || all || fake || argc != 1)
+      if (types || options || readwrite || nomtab || all || fake ||
+         (argc + specseen) != 1)
        die (EX_USAGE, "mount: only root can do that");
   }
 
@@ -1245,7 +1137,19 @@ main (int argc, char *argv[]) {
        create_mtab ();
   }
 
-  switch (argc) {
+  if (specseen) {
+         if (uuid)
+                 spec = get_spec_by_uuid(uuid);
+         else
+                 spec = get_spec_by_volume_label(volumelabel);
+         if (!spec)
+                 die (EX_USAGE, "mount: no such partition found");
+         if (verbose)
+                 printf("mount: mounting %s\n", spec);
+  } else
+         spec = NULL;          /* just for gcc */
+
+  switch (argc+specseen) {
     case 0:
       /* mount -a */
       result = mount_all (types, options);
@@ -1257,13 +1161,32 @@ main (int argc, char *argv[]) {
       /* mount [-nfrvw] [-o options] special | node */
       if (types != NULL)
        usage (stderr, EX_USAGE);
-
-      /* Try to find the other pathname in fstab.  */ 
-      spec = canonicalize (*argv);
-      if ((mc = getmntfile (spec)) == NULL &&
-         (mc = getfsspec (spec)) == NULL && (mc = getfsfile (spec)) == NULL)
-          die (EX_USAGE, "mount: can't find %s in %s or %s",
-               spec, MOUNTED, _PATH_FSTAB);
+      if (specseen) {
+             /* We know the device. Where shall we mount it? */
+             mc = (uuid ? getfsuuidspec (uuid) : getfsvolspec (volumelabel));
+             if (mc == NULL)
+                     mc = getfsspec (spec);
+             if (mc == NULL)
+                     die (EX_USAGE, "mount: cannot find %s in %s",
+                          spec, _PATH_FSTAB);
+             mc->mnt_fsname = spec;
+      } else {
+             /* Try to find the other pathname in fstab.  */
+             spec = canonicalize (*argv);
+             if ((mc = getfsspec (spec)) == NULL &&
+                 (mc = getfsfile (spec)) == NULL &&
+             /* Try noncanonical name in fstab
+                perhaps /dev/cdrom or /dos is a symlink */
+                 (mc = getfsspec (*argv)) == NULL &&
+                 (mc = getfsfile (*argv)) == NULL &&
+             /* Try mtab - maybe this was a remount */
+                 (mc = getmntfile (spec)) == NULL)
+                     die (EX_USAGE, "mount: can't find %s in %s or %s",
+                          spec, _PATH_FSTAB, MOUNTED);
+             /* Earlier mtab was tried first, but this would
+                sometimes try the wrong mount in case mtab had
+                the root device entry wrong. */
+      }
 
       result = mount_one (xstrdup (mc->mnt_fsname), xstrdup (mc->mnt_dir),
                          xstrdup (mc->mnt_type), mc->mnt_opts, options, 0, 0);
@@ -1271,12 +1194,17 @@ main (int argc, char *argv[]) {
 
     case 2:
       /* mount [-nfrvw] [-t vfstype] [-o options] special node */
+      if (specseen) {
+             /* we have spec already */
+             node = argv[0];
+      } else {
+             spec = argv[0];
+             node = argv[1];
+      }
       if (types == NULL)
-       result = mount_one (argv[0], argv[1],
-                           NULL, NULL, options, 0, 0);
+       result = mount_one (spec, node, NULL, NULL, options, 0, 0);
       else if (cdr (types) == NULL)
-       result = mount_one (argv[0], argv[1],
-                           car (types), NULL, options, 0, 0);
+       result = mount_one (spec, node, car (types), NULL, options, 0, 0);
       else
        usage (stderr, EX_USAGE);
       break;
diff --git a/mount/mount_by_label.c b/mount/mount_by_label.c
new file mode 100644 (file)
index 0000000..a48c9de
--- /dev/null
@@ -0,0 +1,143 @@
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include "sundries.h"          /* for xstrdup */
+#include "linux_fs.h"
+#include "mount_by_label.h"
+
+#define PROC_PARTITIONS "/proc/partitions"
+#define DEVLABELDIR    "/dev"
+
+static FILE *procpt;
+
+static void
+procptclose(void) {
+    if (procpt)
+        fclose (procpt);
+    procpt = 0;
+}
+
+static int
+procptopen(void) {
+    return ((procpt = fopen(PROC_PARTITIONS, "r")) != NULL);
+}
+
+static char *
+procptnext(void) {
+   char line[100];
+   char *s;
+   int ma, mi, sz;
+   static char ptname[100];
+
+   while (fgets(line, sizeof(line), procpt)) {
+      if (sscanf (line, " %d %d %d %[^\n]\n", &ma, &mi, &sz, ptname) != 4)
+             continue;
+
+      /* skip extended partitions (heuristic: size 1) */
+      if (sz == 1)
+             continue;
+
+      /* skip entire disk (minor 0, 64, ... on ide; 0, 16, ... on sd) */
+      /* heuristic: partition name ends in a digit */
+      for(s = ptname; *s; s++);
+      if (isdigit(s[-1]))
+             return ptname;
+   }
+   return 0;
+}
+
+#define UUID   1
+#define VOL    2
+
+/* for now, only ext2 is supported */
+static int
+has_right_label(const char *device, int n, const char *label) {
+
+       /* start with a test for ext2, taken from mount_guess_fstype */
+       /* should merge these later */
+       int fd;
+       char *s;
+       struct ext2_super_block e2sb;
+
+       fd = open(device, O_RDONLY);
+       if (fd < 0)
+               return 0;
+
+       if (lseek(fd, 1024, SEEK_SET) != 1024
+           || read(fd, (char *) &e2sb, sizeof(e2sb)) != sizeof(e2sb)
+           || (ext2magic(e2sb) != EXT2_SUPER_MAGIC)) {
+               close(fd);
+               return 0;
+       }
+
+       close(fd);
+
+       /* superblock is ext2 - now what is its label? */
+       s = ((n == UUID) ? e2sb.s_uuid : e2sb.s_volume_name);
+       return (strncmp(s, label, 16) == 0);
+}
+
+static char *
+get_spec_by_x(int n, const char *t) {
+       char *pt;
+       char device[110];
+
+       if(!procptopen())
+               return NULL;
+       while((pt = procptnext()) != NULL) {
+               /* Note: this is a heuristic only - there is no reason
+                  why these devices should live in /dev.
+                  Perhaps this directory should be specifiable by option.
+                  One might for example have /devlabel with links to /dev
+                  for the devices that may be accessed in this way.
+                  (This is useful, if the cdrom on /dev/hdc must not
+                  be accessed.)
+               */
+               sprintf(device, "%s/%s", DEVLABELDIR, pt);
+               if (has_right_label(device, n, t)) {
+                       procptclose();
+                       return xstrdup(device);
+               }
+       }
+       procptclose();
+       return NULL;
+}
+
+static u_char
+fromhex(char c) {
+       if (isdigit(c))
+               return (c - '0');
+       else if (islower(c))
+               return (c - 'a' + 10);
+       else
+               return (c - 'A' + 10);
+}
+
+char *
+get_spec_by_uuid(const char *s) {
+       u_char uuid[16];
+       int i;
+
+       if (strlen(s) != 36 ||
+           s[8] != '-' || s[13] != '-' || s[18] != '-' || s[23] != '-')
+               goto bad_uuid;
+       for (i=0; i<16; i++) {
+           if (*s == '-') s++;
+           if (!isxdigit(s[0]) || !isxdigit(s[1]))
+                   goto bad_uuid;
+           uuid[i] = ((fromhex(s[0])<<4) | fromhex(s[1]));
+           s += 2;
+       }
+       return get_spec_by_x(UUID, uuid);
+
+ bad_uuid:
+       die(EX_USAGE, "mount: bad UUID");
+}
+
+char *
+get_spec_by_volume_label(const char *s) {
+       return get_spec_by_x(VOL, s);
+}
+
diff --git a/mount/mount_by_label.h b/mount/mount_by_label.h
new file mode 100644 (file)
index 0000000..21c2d84
--- /dev/null
@@ -0,0 +1,2 @@
+char *get_spec_by_uuid(const char *uuid);
+char *get_spec_by_volume_label(const char *volumelabel);
index 5f033452db0f31bc8c8e3314428da7d99f137bd2..aeb7edfb376a30bb0a4eef8ba9be9f3ae02d4afc 100644 (file)
@@ -1,16 +1,36 @@
+#ifndef MS_RDONLY
 #define MS_RDONLY       1      /* Mount read-only */
+#endif
+#ifndef MS_NOSUID
 #define MS_NOSUID       2      /* Ignore suid and sgid bits */
+#endif
+#ifndef MS_NODEV
 #define MS_NODEV        4      /* Disallow access to device special files */
+#endif
+#ifndef MS_NOEXEC
 #define MS_NOEXEC       8      /* Disallow program execution */
+#endif
+#ifndef MS_SYNCHRONOUS
 #define MS_SYNCHRONOUS 16      /* Writes are synced at once */
+#endif
+#ifndef MS_REMOUNT
 #define MS_REMOUNT     32      /* Alter flags of a mounted FS */
+#endif
+#ifndef MS_MANDLOCK
 #define MS_MANDLOCK    64      /* Allow mandatory locks on an FS */
+#endif
+#ifndef MS_NOATIME
 #define MS_NOATIME     1024    /* Do not update access times. */
+#endif
+#ifndef MS_NODIRATIME
 #define MS_NODIRATIME   2048    /* Do not update directory access times */
+#endif
 /*
  * Magic mount flag number. Has to be or-ed to the flag values.
  */
 #ifndef MS_MGC_VAL
 #define MS_MGC_VAL 0xC0ED0000  /* magic flag number to indicate "new" flags */
 #endif
+#ifndef MS_MGC_MSK
 #define MS_MGC_MSK 0xffff0000  /* magic flag number mask */
+#endif
diff --git a/mount/mount_guess_fstype.c b/mount/mount_guess_fstype.c
new file mode 100644 (file)
index 0000000..b6b9e65
--- /dev/null
@@ -0,0 +1,252 @@
+/*
+ * Thu Jul 14 07:32:40 1994: faith@cs.unc.edu added changes from Adam
+ * J. Richter (adam@adam.yggdrasil.com) so that /proc/filesystems is used
+ * if no -t option is given.  I modified his patches so that, if
+ * /proc/filesystems is not available, the behavior of mount is the same as
+ * it was previously.
+ *
+ * Wed Feb 8 09:23:18 1995: Mike Grupenhoff <kashmir@umiacs.UMD.EDU> added
+ * a probe of the superblock for the type before /proc/filesystems is
+ * checked.
+ *
+ * Fri Apr  5 01:13:33 1996: quinlan@bucknell.edu, fixed up iso9660 autodetect
+ *
+ * Wed Nov  11 11:33:55 1998: K.Garloff@ping.de, try /etc/filesystems before
+ * /proc/filesystems
+ *
+ * aeb - many changes.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include "linux_fs.h"
+#include "mount_guess_fstype.h"
+#include "sundries.h"          /* for xstrdup */
+
+#define ETC_FILESYSTEMS                "/etc/filesystems"
+#define PROC_FILESYSTEMS       "/proc/filesystems"
+
+#define SIZE(a) (sizeof(a)/sizeof(a[0]))
+
+/* Most file system types can be recognized by a `magic' number
+   in the superblock.  Note that the order of the tests is
+   significant: by coincidence a filesystem can have the
+   magic numbers for several file system types simultaneously.
+   For example, the romfs magic lives in the 1st sector;
+   xiafs does not touch the 1st sector and has its magic in
+   the 2nd sector; ext2 does not touch the first two sectors. */
+
+static inline unsigned short
+swapped(unsigned short a) {
+     return (a>>8) | (a<<8);
+}
+
+/*
+    char *guess_fstype_from_superblock(const char *device);
+
+    Probes the device and attempts to determine the type of filesystem
+    contained within.
+
+    Original routine by <jmorriso@bogomips.ww.ubc.ca>; made into a function
+    for mount(8) by Mike Grupenhoff <kashmir@umiacs.umd.edu>.
+    Read the superblock only once - aeb
+    Added a test for iso9660 - aeb
+    Added a test for high sierra (iso9660) - quinlan@bucknell.edu
+    Corrected the test for xiafs - aeb
+    Added romfs - aeb
+    Added ufs from a patch by jj. But maybe there are several types of ufs?
+
+    Currently supports: minix, ext, ext2, xiafs, iso9660, romfs, ufs
+*/
+static char
+*magic_known[] = { "minix", "ext", "ext2", "xiafs", "iso9660", "romfs",
+                  "ufs" };
+
+static int
+tested(const char *device) {
+    char **m;
+
+    for (m = magic_known; m - magic_known < SIZE(magic_known); m++)
+        if (!strcmp(*m, device))
+           return 1;
+    return 0;
+}
+
+static char *
+fstype(const char *device) {
+    int fd;
+    char *type = NULL;
+    union {
+       struct minix_super_block ms;
+       struct ext_super_block es;
+       struct ext2_super_block e2s;
+    } sb;
+    union {
+       struct xiafs_super_block xiasb;
+       char romfs_magic[8];
+    } xsb;
+    struct ufs_super_block ufssb;
+    union {
+       struct iso_volume_descriptor iso;
+       struct hs_volume_descriptor hs;
+    } isosb;
+    struct stat statbuf;
+
+    /* opening and reading an arbitrary unknown path can have
+       undesired side effects - first check that `device' refers
+       to a block device */
+    if (stat (device, &statbuf) || !S_ISBLK(statbuf.st_mode))
+      return 0;
+
+    fd = open(device, O_RDONLY);
+    if (fd < 0)
+      return 0;
+
+    if (lseek(fd, 1024, SEEK_SET) != 1024
+       || read(fd, (char *) &sb, sizeof(sb)) != sizeof(sb))
+        goto io_error;
+
+    if (ext2magic(sb.e2s) == EXT2_SUPER_MAGIC
+       || ext2magic(sb.e2s) == EXT2_PRE_02B_MAGIC
+       || ext2magic(sb.e2s) == swapped(EXT2_SUPER_MAGIC))
+        type = "ext2";
+
+    else if (minixmagic(sb.ms) == MINIX_SUPER_MAGIC
+            || minixmagic(sb.ms) == MINIX_SUPER_MAGIC2)
+        type = "minix";
+
+    else if (extmagic(sb.es) == EXT_SUPER_MAGIC)
+        type = "ext";
+
+    if (!type) {
+        if (lseek(fd, 0, SEEK_SET) != 0
+            || read(fd, (char *) &xsb, sizeof(xsb)) != sizeof(xsb))
+             goto io_error;
+
+        if (xiafsmagic(xsb.xiasb) == _XIAFS_SUPER_MAGIC)
+             type = "xiafs";
+        else if(!strncmp(xsb.romfs_magic, "-rom1fs-", 8))
+             type = "romfs";
+    }
+
+    if (!type) {
+        if (lseek(fd, 8192, SEEK_SET) != 8192
+            || read(fd, (char *) &ufssb, sizeof(ufssb)) != sizeof(ufssb))
+             goto io_error;
+
+        if (ufsmagic(ufssb) == UFS_SUPER_MAGIC) /* also test swapped version? */
+             type = "ufs";
+    }
+
+    if (!type) {
+        if (lseek(fd, 0x8000, SEEK_SET) != 0x8000
+            || read(fd, (char *) &isosb, sizeof(isosb)) != sizeof(isosb))
+             goto io_error;
+
+        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";
+    }
+
+    close (fd);
+    return(type);
+
+io_error:
+    perror(device);
+    close(fd);
+    return 0;
+}
+
+char *
+guess_fstype_from_superblock(const char *spec) {
+      char *type = fstype(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
+           printf ("       I will try all types mentioned in %s or %s\n",
+                   ETC_FILESYSTEMS, PROC_FILESYSTEMS);
+      }
+      return type;
+}
+
+static FILE *procfs;
+
+static void
+procfsclose(void) {
+       if (procfs)
+               fclose (procfs);
+       procfs = 0;
+}
+
+static int
+procfsopen(void) {
+       procfs = fopen(ETC_FILESYSTEMS, "r");
+       if (!procfs)
+               procfs = fopen(PROC_FILESYSTEMS, "r");
+       return (procfs != NULL);
+}
+
+static char *
+procfsnext(void) {
+   char line[100];
+   static char fsname[50];
+
+   while (fgets(line, sizeof(line), procfs)) {
+      if (sscanf (line, "nodev %[^\n]\n", fsname) == 1) continue;
+      if (sscanf (line, " %[^ \n]\n", fsname) != 1) continue;
+      return fsname;
+   }
+   return 0;
+}
+
+int
+is_in_procfs(const char *type) {
+    char *fsname;
+
+    if (procfsopen()) {
+       while ((fsname = procfsnext()) != NULL)
+         if (!strcmp(fsname, type))
+           return 1;
+    }
+    return 0;
+}
+
+int
+procfsloop(int (*mount_fn)(struct mountargs *), struct mountargs *args,
+          char **type) {
+   char *fsname;
+
+   if (!procfsopen())
+     return -1;
+   while ((fsname = procfsnext()) != NULL) {
+      if (tested (fsname))
+        continue;
+      args->type = fsname;
+      if ((*mount_fn) (args) == 0) {
+        *type = xstrdup(fsname);
+        procfsclose();
+        return 0;
+      } else if (errno != EINVAL) {
+         *type = "guess";
+        procfsclose();
+        return 1;
+      }
+   }
+   procfsclose();
+   *type = NULL;
+
+   return -1;
+}
+
+int
+have_procfs(void) {
+       return procfs != NULL;
+}
diff --git a/mount/mount_guess_fstype.h b/mount/mount_guess_fstype.h
new file mode 100644 (file)
index 0000000..3663f74
--- /dev/null
@@ -0,0 +1,15 @@
+struct mountargs {
+       const char *spec;
+       const char *node;
+       const char *type;
+       int flags;
+       void *data;
+};
+
+extern int verbose;
+
+char *guess_fstype_from_superblock(const char *device);
+int procfsloop(int (*mount_fn)(struct mountargs *), struct mountargs *args,
+              char **type);
+int is_in_procfs(const char *fstype);
+int have_procfs(void);
index fd936466958b40ed31401242ec35c60f02f1cb9c..dd55d75a5881d974405e1e67049a8eac9ff4fabc 100644 (file)
@@ -151,10 +151,17 @@ int nfsmount(const char *spec, const char *node, int *flags,
                goto fail;
        }
        strcpy(hostdir, spec);
-       if ((s = (strchr(hostdir, ':')))) {
+       if ((s = strchr(hostdir, ':'))) {
                hostname = hostdir;
                dirname = s + 1;
                *s = '\0';
+               /* Ignore all but first hostname in replicated mounts
+                  until they can be fully supported. (mack@sgi.com) */
+               if ((s = strchr(hostdir, ','))) {
+                       *s = '\0';
+                       fprintf(stderr, "mount: warning: "
+                               "multiple hostnames not supported\n");
+               }
        } else {
                fprintf(stderr, "mount: "
                        "directory to mount not in host:dir format\n");
@@ -272,17 +279,24 @@ int nfsmount(const char *spec, const char *node, int *flags,
                                mountvers = val;
                        else if (!strcmp(opt, "nfsprog"))
                                nfsprog = val;
-                       else if (!strcmp(opt, "nfsvers"))
+                       else if (!strcmp(opt, "nfsvers") ||
+                                !strcmp(opt, "vers"))
                                nfsvers = val;
-                       else if (!strcmp(opt, "namlen")) {
+                       else if (!strcmp(opt, "proto")) {
+                               if (!strncmp(opteq+1, "tcp", 3))
+                                       tcp = 1;
+                               else if (!strncmp(opteq+1, "udp", 3))
+                                       tcp = 0;
+                               else
+                                       printf("Warning: Unrecognized proto= option.\n");
+                       } else if (!strcmp(opt, "namlen")) {
 #if NFS_MOUNT_VERSION >= 2
                                if (nfs_mount_version >= 2)
                                        data.namlen = val;
                                else
 #endif
                                printf("Warning: Option namlen is not supported.\n");
-                       }
-                       else if (!strcmp(opt, "addr"))
+                       } else if (!strcmp(opt, "addr"))
                                /* ignore */;
                        else {
                                printf("unknown nfs mount parameter: "
index 6f539c24fa03ead48cf2bf60382452f8c190c7df..91fbeec6acb7ecda4f409279e15f8766c9381b09 100644 (file)
@@ -3,6 +3,9 @@
  * It was generated using rpcgen.
  */
 
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+
 #include "nfsmount.h"
 /*
  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
@@ -40,9 +43,7 @@
 /* from @(#)mount.x    1.3 91/03/11 TIRPC 1.0 */
 
 bool_t
-xdr_fhandle(xdrs, objp)
-       XDR *xdrs;
-       fhandle objp;
+xdr_fhandle(XDR *xdrs, fhandle objp)
 {
 
         register long *buf;
@@ -54,9 +55,7 @@ xdr_fhandle(xdrs, objp)
 }
 
 bool_t
-xdr_fhstatus(xdrs, objp)
-       XDR *xdrs;
-       fhstatus *objp;
+xdr_fhstatus(XDR *xdrs, fhstatus *objp)
 {
 
         register long *buf;
@@ -70,14 +69,14 @@ xdr_fhstatus(xdrs, objp)
                         return (FALSE);
                 }
                break;
+       default:
+               break;
        }
        return (TRUE);
 }
 
 bool_t
-xdr_dirpath(xdrs, objp)
-       XDR *xdrs;
-       dirpath *objp;
+xdr_dirpath(XDR *xdrs, dirpath *objp)
 {
 
         register long *buf;
@@ -89,9 +88,7 @@ xdr_dirpath(xdrs, objp)
 }
 
 bool_t
-xdr_name(xdrs, objp)
-       XDR *xdrs;
-       name *objp;
+xdr_name(XDR *xdrs, name *objp)
 {
 
         register long *buf;
@@ -103,9 +100,7 @@ xdr_name(xdrs, objp)
 }
 
 bool_t
-xdr_mountlist(xdrs, objp)
-       XDR *xdrs;
-       mountlist *objp;
+xdr_mountlist(XDR *xdrs, mountlist *objp)
 {
 
         register long *buf;
@@ -117,9 +112,7 @@ xdr_mountlist(xdrs, objp)
 }
 
 bool_t
-xdr_mountbody(xdrs, objp)
-       XDR *xdrs;
-       mountbody *objp;
+xdr_mountbody(XDR *xdrs, mountbody *objp)
 {
 
         register long *buf;
@@ -137,9 +130,7 @@ xdr_mountbody(xdrs, objp)
 }
 
 bool_t
-xdr_groups(xdrs, objp)
-       XDR *xdrs;
-       groups *objp;
+xdr_groups(XDR *xdrs, groups *objp)
 {
 
         register long *buf;
@@ -151,9 +142,7 @@ xdr_groups(xdrs, objp)
 }
 
 bool_t
-xdr_groupnode(xdrs, objp)
-       XDR *xdrs;
-       groupnode *objp;
+xdr_groupnode(XDR *xdrs, groupnode *objp)
 {
 
         register long *buf;
@@ -168,9 +157,7 @@ xdr_groupnode(xdrs, objp)
 }
 
 bool_t
-xdr_exports(xdrs, objp)
-       XDR *xdrs;
-       exports *objp;
+xdr_exports(XDR *xdrs, exports *objp)
 {
 
         register long *buf;
@@ -182,9 +169,7 @@ xdr_exports(xdrs, objp)
 }
 
 bool_t
-xdr_exportnode(xdrs, objp)
-       XDR *xdrs;
-       exportnode *objp;
+xdr_exportnode(XDR *xdrs, exportnode *objp)
 {
 
         register long *buf;
@@ -202,9 +187,7 @@ xdr_exportnode(xdrs, objp)
 }
 
 bool_t
-xdr_ppathcnf(xdrs, objp)
-       XDR *xdrs;
-       ppathcnf *objp;
+xdr_ppathcnf(XDR *xdrs, ppathcnf *objp)
 {
 
         register long *buf;
index 4506924aac0696d64ad50f7f6d5b705d2a56a0c6..d7ace1b2df0759b0a6df1610e3c81b6896a8b5bb 100644 (file)
@@ -29,12 +29,12 @@ xmalloc (size_t size) {
      void *t;
 
      if (size == 0)
-         return NULL;
+          return NULL;
 
      t = malloc (size);
      if (t == NULL)
-         die (EX_SYSERR, "not enough memory");
-  
+          die (EX_SYSERR, "not enough memory");
+
      return t;
 }
 
@@ -43,12 +43,12 @@ xstrdup (const char *s) {
      char *t;
 
      if (s == NULL)
-         return NULL;
+          return NULL;
+
      t = strdup (s);
 
      if (t == NULL)
-         die (EX_SYSERR, "not enough memory");
+          die (EX_SYSERR, "not enough memory");
 
      return t;
 }
index a557e18713cbcfddcbd2d56b3674380d8b0ac0bd..ebd67ced669223c210b5c2576364d678dea9005d 100644 (file)
@@ -1,24 +1,36 @@
 # Find out whether we can include <sys/swap.h>
 # and whether libc thinks that swapon() has two arguments.
-# Of course this will fail if <sys/swap.h> exists but belongs
-# to a libc that is not in use at present.
+
+# Prepare test
 CC=${CC-cc}
 compile="$CC -o conftest conftest.c >/dev/null 2>&1"
 rm -f conftest conftest.c swapargs.h
+
+# What include files shall we try?
+# Unfortunately, recent versions of swap.h use PAGE_SIZE and hence need page.h
+# It is used only in mkswap, not in swapon/swapoff, so we might just pick any
+# random value (like #define PAGE_SIZE 4096) instead of including page.h.
 SWAPH=
-if [ -f /usr/include/sys/swap.h ]; then SWAPH="#include <sys/swap.h>"; fi
-echo $SWAPH > conftest.c
+PAGEH=
+if [ -f /usr/include/sys/swap.h ]; then
+       SWAPH="#include <sys/swap.h>"
+       if [ -f /usr/include/asm/page.h ]; then
+               PAGEH="#include <asm/page.h>"
+       fi
+fi
+echo $PAGEH > conftest.c
+echo $SWAPH >> conftest.c
 echo '#include <unistd.h>
 main(){ exit(0); swapon("/dev/null", 0); }' >> conftest.c
 eval $compile
 if test -s conftest && ./conftest 2>/dev/null; then
        echo "#define SWAPON_HAS_TWO_ARGS" > swapargs.h
+       echo $PAGEH >> swapargs.h
        echo $SWAPH >> swapargs.h
 else
        echo > swapargs.h
        echo "
 Your libc thinks that swapon has 1 arg only.
-Define SWAPON_NEEDS_TWO_ARGS in swapon.c if you want to use priorities.
 " 1>&2
 fi
 rm -f conftest conftest.c
diff --git a/mount/swap_constants.h b/mount/swap_constants.h
new file mode 100644 (file)
index 0000000..c7e8b4c
--- /dev/null
@@ -0,0 +1,15 @@
+/*
+ * It is too painful to get these out of <linux/swap.h>
+ * (which again requires <asm/page.h> etc).
+ * These exist since Linux 1.3.2.
+ */
+
+#ifndef SWAP_FLAG_PREFER
+#define SWAP_FLAG_PREFER       0x8000  /* set if swap priority specified */
+#endif
+#ifndef SWAP_FLAG_PRIO_MASK
+#define SWAP_FLAG_PRIO_MASK    0x7fff
+#endif
+#ifndef SWAP_FLAG_PRIO_SHIFT
+#define SWAP_FLAG_PRIO_SHIFT   0
+#endif
index 0ebb450a8ffffc3643897e9e777d4adae1ed1804..74f61eea46fa06d42839845c11c674bb364edb38 100644 (file)
@@ -74,7 +74,10 @@ Provide help
 Display version
 .TP
 .B \-s
-Display swap usage summary by device
+Display swap usage summary by device.
+This option is only available if
+.I /proc/swaps
+exists (probably not before kernel 2.1.25).
 .TP
 .B \-a
 All devices marked as ``sw'' swap devices in
@@ -104,6 +107,10 @@ entries in
 when the
 .B \-a
 flag is given.
+.SH NOTE
+You should not use
+.B swapon
+on a file with holes.
 .SH SEE ALSO
 .BR swapon "(2), " swapoff "(2), " fstab "(5), " init "(8), " mkswap (8),
 .BR rc "(8), " mount (8)
@@ -120,8 +127,3 @@ ascii filesystem description table
 The
 .B swapon
 command appeared in 4.0BSD.
-.SH AUTHORS
-See the Linux
-.BR mount (8)
-man page for a complete author list.  Primary contributors include Doug
-Quale, H. J. Lu, Rick Sladkey, and Stephen Tweedie.
index 5fdd15c5d48892980a69f9439a8b9d24899ad975..41d1f3fce2f68f28ee5ba7f1ee57c631e38e2bf9 100644 (file)
@@ -10,7 +10,8 @@
 #include <string.h>
 #include <mntent.h>
 #include <errno.h>
-#include "swap.h"
+#include <sys/stat.h>
+#include "swap_constants.h"
 #include "swapargs.h"
 
 #define streq(s, t)    (strcmp ((s), (t)) == 0)
@@ -18,7 +19,7 @@
 #define        _PATH_FSTAB     "/etc/fstab"
 #define PROC_SWAPS      "/proc/swaps"
 
-/* #define SWAPON_NEEDS_TWO_ARGS */
+#define SWAPON_NEEDS_TWO_ARGS
 
 /* Nonzero for chatty (-v).  This is a nonstandard flag (not in BSD).  */
 int verbose = 0;
@@ -77,12 +78,34 @@ static int
 swap (const char *special, int prio)
 {
   int status;
+  struct stat st;
 
   if (verbose)
-    printf("%s on device %s\n", program_name, special);
+    printf("%s on %s\n", program_name, special);
 
   if (streq (program_name, "swapon")) {
+    if (stat(special, &st) < 0) {
+        fprintf (stderr, "swapon: cannot stat %s: %s\n", special, strerror (errno));
+       return -1;
+    }
+
+    if ((st.st_mode & 07077) != 0) {
+        fprintf(stderr, "swapon: warning: %s has insecure permissions %04o, "
+                       "0600 suggested\n", special, st.st_mode & 07777);
+    }
+
+    /* test for holes by LBT */
+    if (S_ISREG(st.st_mode)) {
+       if (st.st_blocks * 512 < st.st_size) {
+           fprintf(stderr,
+                   "swapon: Skipping file %s - it appears to have holes.\n",
+                   special);
+           return -1;
+       }
+    }
+
 #ifdef SWAPON_NEEDS_TWO_ARGS
+    {
      int flags = 0;
 
 #ifdef SWAP_FLAG_PREFER
@@ -94,6 +117,7 @@ swap (const char *special, int prio)
      }
 #endif
      status = swapon (special, flags);
+    }
 #else
      status = swapon (special);
 #endif
index 6f28213b4983bed9753290d8fbc721202cedfb09..ac233a70ba3e8d59a14a56662e88bc6f5de4ce7a 100644 (file)
  * 960823: aeb - also try umount(spec) when umount(node) fails
  * 970307: aeb - canonise names from fstab
  * 970726: aeb - remount read-only in cases where umount fails
+ * 980810: aeb - umount2 support
+ * 981222: aeb - If mount point or special file occurs several times
+ *               in mtab, try them all, with last one tried first
+ *             - Differentiate "user" and "users" key words in fstab
  */
 
 #include <unistd.h>
@@ -28,6 +32,7 @@
 #include <sys/mount.h>
 #include "mount_constants.h"
 #include "sundries.h"
+#include "getusername.h"
 #include "lomount.h"
 #include "loop.h"
 #include "fstab.h"
 #include <arpa/inet.h>
 #endif
 
+static int umount2(const char *path, int flags);
 
-#ifdef notyet
-/* Nonzero for force umount (-f).  This needs kernel support we don't have.  */
+#ifdef MNT_FORCE
+/* Interesting ... it seems libc knows about MNT_FORCE and presumably
+   about umount2 as well -- need not do anything */
+#else /* MNT_FORCE */
+
+/* Does the present kernel source know about umount2? */
+#include <linux/unistd.h>
+#ifdef __NR_umount2
+_syscall2(int, umount2, const char *, path, int, flags);
+#else /* __NR_umount2 */
+static int
+umount2(const char *path, int flags) {
+       fprintf(stderr, "umount: compiled without support for -f\n");
+       errno = ENOSYS;
+       return -1;
+}
+#endif /* __NR_umount2 */
+
+/* dare not try to include <linux/mount.h> -- lots of errors */
+#define MNT_FORCE 1
+
+#endif /* MNT_FORCE */
+
+/* Nonzero for force umount (-f).  There is kernel support since 2.1.116.  */
 int force = 0;
-#endif
 
 /* When umount fails, attempt a read-only remount (-r). */
 int remount = 0;
@@ -169,7 +196,7 @@ static void complain(int err, const char *dev) {
    on a non-fatal error.  We lock/unlock around each umount.  */
 static int
 umount_one (const char *spec, const char *node, const char *type,
-           const char *opts)
+           const char *opts, struct mntentchn *mc)
 {
   int umnt_err, umnt_err2;
   int isroot;
@@ -195,7 +222,22 @@ umount_one (const char *spec, const char *node, const char *type,
  
 
   umnt_err = umnt_err2 = 0;
-  res = umount (node);
+  if (force) {
+       /* completely untested - 2.1.116 only has some support in nfs case */
+       /* probably this won't work */
+       int flags = MNT_FORCE;
+
+       res = umount2 (node, flags);
+       if (res == -1) {
+              perror("umount2");
+              if (errno == ENOSYS) {
+                      if (verbose)
+                              printf("no umount2, trying umount...\n");
+                      res = umount (node);
+              }
+       }
+  } else
+       res = umount (node);
   if (res < 0) {
        umnt_err = errno;
        /* A device might have been mounted on a node that has since
@@ -238,11 +280,9 @@ umount_one (const char *spec, const char *node, const char *type,
        printf ("%s umounted\n", spec);
 
       if (!nomtab && mtab_is_writable()) {
-         struct mntentchn *mc;
                                /* Special stuff for loop devices */
-
-         if ((mc = getmntfile (spec)) || (mc = getmntfile (node))) {
-            char *opts;
+         if (mc) {
+            char *optl;
 
             /* old style mtab line? */
             if (streq(mc->mnt_type, "loop"))
@@ -250,10 +290,10 @@ umount_one (const char *spec, const char *node, const char *type,
                      goto fail;
 
             /* new style mtab line? */
-            opts = mc->mnt_opts ? xstrdup(mc->mnt_opts) : "";
-            for (opts = strtok (opts, ","); opts; opts = strtok (NULL, ",")) {
-                if (!strncmp(opts, "loop=", 5)) {
-                    if (del_loop(opts+5))
+            optl = mc->mnt_opts ? xstrdup(mc->mnt_opts) : "";
+            for (optl = strtok (optl, ","); optl; optl = strtok (NULL, ",")) {
+                if (!strncmp(optl, "loop=", 5)) {
+                    if (del_loop(optl+5))
                       goto fail;
                     break;
                 }
@@ -286,6 +326,28 @@ fail:
   return 1;
 }
 
+/*
+ * Why this loop?
+ * 1. People who boot a system with a bad fstab root entry
+ *    will get an incorrect "/dev/foo on /" in mtab.
+ *    If later /dev/foo is actually mounted elsewhere,
+ *    it will occur twice in mtab.
+ * 2. With overmounting one can get the situation that
+ *    the same filename is used as mount point twice.
+ * In both cases, it is best to try the last occurrence first.
+ */
+static int
+umount_one_bw (const char *file, struct mntentchn *mc) {
+     int res = 1;
+
+     while (res && mc) {
+         res = umount_one(mc->mnt_fsname, mc->mnt_dir,
+                          mc->mnt_type, mc->mnt_opts, mc);
+         mc = getmntfilesbackward (file, mc);
+     }
+     return res;
+}
+
 /* Unmount all filesystems of type VFSTYPES found in mtab.  Since we are
    concurrently updating mtab after every succesful umount, we have to
    slurp in the entire file before we start.  This isn't too bad, because
@@ -302,7 +364,7 @@ umount_all (string_list types) {
      for (mc = hd->prev; mc != hd; mc = mc->prev) {
          if (matching_type (mc->mnt_type, types)) {
               errors |= umount_one (mc->mnt_fsname, mc->mnt_dir,
-                                    mc->mnt_type, mc->mnt_opts);
+                                    mc->mnt_type, mc->mnt_opts, mc);
          }
      }
 
@@ -325,9 +387,9 @@ static struct option longopts[] =
 };
 
 char *usage_string = "\
-usage: umount [-hV]\n\
-       umount -a [-r] [-n] [-v] [-t vfstypes]\n\
-       umount [-r] [-n] [-v] special | node...\n\
+Usage: umount [-hV]\n\
+       umount -a [-f] [-r] [-n] [-v] [-t vfstypes]\n\
+       umount [-f] [-r] [-n] [-v] special | node...\n\
 ";
 
 static void
@@ -350,22 +412,19 @@ main (int argc, char *argv[])
   char *file;
   int result = 0;
 
-  while ((c = getopt_long (argc, argv, "afhnrvVt:", longopts, NULL)) != EOF)
+  while ((c = getopt_long (argc, argv, "afhnrt:vV",
+                          longopts, NULL)) != EOF)
     switch (c) {
       case 'a':                        /* umount everything */
        ++all;
        break;
-      case 'f':                        /* force umount (needs kernel support) */
-#if 0
+      case 'f':                        /* force umount */
        ++force;
-#else
-       die (2, "umount: forced umount not supported yet");
-#endif
        break;
       case 'h':                        /* help */
        usage (stdout, 0);
        break;
-      case 'n':
+      case 'n':                        /* do not write in /etc/mtab */
        ++nomtab;
        break;
       case 'r':                        /* remount read-only if umount fails */
@@ -390,7 +449,7 @@ main (int argc, char *argv[])
   if (getuid () != geteuid ())
     {
       suid = 1;
-      if (all || types || nomtab)
+      if (all || types || nomtab || force)
        die (2, "umount: only root can do that");
     }
 
@@ -408,13 +467,15 @@ main (int argc, char *argv[])
        if (verbose > 1)
          printf("Trying to umount %s\n", file);
 
-       mc = getmntfile (file);
+       mc = getmntfilesbackward (file, NULL);
        if (!mc && verbose)
          printf("Could not find %s in mtab\n", file);
 
        if (suid) {
          if (!mc)
            die (2, "umount: %s is not mounted (according to mtab)", file);
+         if (getmntfilesbackward (file, mc))
+           die (2, "umount: it seems %s is mounted multiple times", file);
          if (!(fs = getfsspec (file)) && !(fs = getfsfile (file)))
            die (2, "umount: %s is not in the fstab (and you are not root)",
                 file);
@@ -424,22 +485,46 @@ main (int argc, char *argv[])
                  !streq (mc->mnt_dir, canonicalize (fs->mnt_dir)))) {
            die (2, "umount: %s mount disagrees with the fstab", file);
          }
+
+         /* User mounting and unmounting is allowed only
+            if fstab contains the option `user' or `users' */
+         /* The option `users' allows arbitrary users to mount
+            and unmount - this may be a security risk. */
+         /* The option `user' only allows unmounting by the user
+            that mounted. */
+         /* A convenient side effect is that the user who mounted
+            is visible in mtab. */
          options = parse_list (fs->mnt_opts);
          while (options) {
-             if (streq (car (options), "user"))
+             if (streq (car (options), "user") ||
+                 streq (car (options), "users"))
                break;
              options = cdr (options);
          }
          if (!options)
            die (2, "umount: only root can unmount %s from %s",
                 fs->mnt_fsname, fs->mnt_dir);
+         if (streq (car (options), "user")) {
+             char *user = getusername();
+
+             options = parse_list (mc->mnt_opts);
+             while (options) {
+                 char *co = car (options);
+                 if (!strncmp(co, "user=", 5)) {
+                     if (!user || !streq(co+5,user))
+                         die(2, "umount: only %s can unmount %s from %s",
+                             co+5, fs->mnt_fsname, fs->mnt_dir);
+                     break;
+                 }
+                 options = cdr (options);
+             }
+         }
        }
 
        if (mc)
-           result = umount_one (xstrdup(mc->mnt_fsname), xstrdup(mc->mnt_dir),
-                                xstrdup(mc->mnt_type), xstrdup(mc->mnt_opts));
+           result = umount_one_bw (file, mc);
        else
-           result = umount_one (*argv, *argv, *argv, *argv);
+           result = umount_one (*argv, *argv, *argv, *argv, NULL);
 
        argv++;
 
index 0c9363d37ea45f10ec7441bd775bcd6e76c21e87..790c447bf8cca64315c2b545287238d942eeb4bf 100644 (file)
@@ -1 +1,2 @@
-char version[] = "mount-2.8";
+#include "../version.h"
+char version[] = "mount-" UTIL_LINUX_VERSION;
index 9085fa9652946672753d6c7e087fafacb8c8d689..91aa32d1d7d9612d35d5790c920874fe93de16c3 100644 (file)
@@ -11,9 +11,9 @@ include ../MCONFIG
 
 MAN1=          arch.1 readprofile.1
 
-MAN8=          ctrlaltdel.8 cytune.8 dmesg.8 \
+MAN8=          ctrlaltdel.8 cytune.8 dmesg.8 hwclock.8 \
                ipcrm.8 ipcs.8 kbdrate.8 ramsize.8 renice.8 \
-               rootflags.8 setsid.8 swapdev.8 tunelp.8 \
+               rootflags.8 setsid.8 sln.8 swapdev.8 tunelp.8 \
                vidmode.8 
 
 # Where to put binaries?
@@ -23,15 +23,14 @@ BIN=            arch dmesg
 
 USRBIN=                cytune ipcrm ipcs renice readprofile setsid tunelp
 
-SBIN=          sln ctrlaltdel kbdrate
+SBIN=          ctrlaltdel hwclock kbdrate
 
-ifneq "$(CPU)" "sparc"
-MAN8:= $(MAN8) hwclock.8
-SBIN:=$(SBIN) hwclock
+ifeq "$(HAVE_SLN)" "no"
+SBIN:=$(SBIN) sln
 endif
 
 ifeq "$(CPU)" "intel"
-MAN8:= $(MAN8) rdev.8
+MAN8:=$(MAN8) rdev.8
 USRBIN:=$(USRBIN) rdev
 endif
 
@@ -49,7 +48,8 @@ sln: sln.c
 arch: arch.o
 hwclock.o: hwclock.c shhopt.h
 hwclock: hwclock.o shhopt.o
-ctrlaltdel: ctrlaltdel.o
+ctrlaltdel.o: ctrlaltdel.c $(LIB)/linux_reboot.h
+ctrlaltdel: ctrlaltdel.o $(LIB)/my_reboot.o
 ipcrm: ipcrm.o
 ipcs: ipcs.o
 kbdrate: kbdrate.o
index e5565d70486d2b677abe8d0918c910344a43ab68..c754fd0589f67a76a9da23324aac42b5d4a1344b 100644 (file)
@@ -7,24 +7,24 @@
 #include <stdio.h>
 #include <unistd.h>
 #include <string.h>
-
-int reboot(int magic, int magictoo, int flag);
+#include "linux_reboot.h"
 
 int
 main(int argc, char *argv[]) {
 
        if(geteuid()) {
-               fprintf(stderr, "You must be root to set the Ctrl-Alt-Del behaviour.\n");
+               fprintf(stderr,
+                   "You must be root to set the Ctrl-Alt-Del behaviour.\n");
                exit(1);
        }
 
        if(argc == 2 && !strcmp("hard", argv[1])) {
-               if(reboot(0xfee1dead, 672274793, 0x89abcdef) < 0) {
+               if(my_reboot(LINUX_REBOOT_CMD_CAD_ON) < 0) {
                        perror("ctrlaltdel: reboot");
                        exit(1);
                }
        } else if(argc == 2 && !strcmp("soft", argv[1])) {
-               if(reboot(0xfee1dead, 672274793, 0) < 0) {
+               if(my_reboot(LINUX_REBOOT_CMD_CAD_OFF) < 0) {
                        perror("ctrlaltdel: reboot");
                        exit(1);
                }
index ec8b00762d6a97e289836c8d3c22b6443c8acd2b..58f4a259e38b688692aaca6fc9cc9102edd6da12 100644 (file)
@@ -55,8 +55,17 @@ Set the Hardware Clock to the time given by the
 option.
 .TP
 .B \-\-hctosys
-Set the System Time from the Hardware Clock.  This is a good option to use
-in one of the system startup scripts.
+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 /usr/lib/zoneinfo, as 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.
@@ -118,11 +127,19 @@ Time.  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 
 .I hwclock.
-.PP
-If you don't specify 
-.B --utc 
-when you should, or vice versa, both setting and querying of the
-Hardware Clock will be messed up.
+
+In order to avoid any possible misunderstandings: all conversation
+with the program
+.I hwclock
+is done in local time. If you have your clock in UTC
+(as is common on a Unix system) then the option
+.B --utc
+tells
+.I hwclock
+to do the appropriate conversions: `hwclock \-\-show \-\-utc'
+will tell you the local time, assuming the hardware clock is in UTC,
+and `hwclock \-\-set \-\-date="XXX" \-\-utc' will set the
+hardware clock to the UTC equivalent of the local time XXX.
 .TP
 .B \-\-directisa
 is meaningful only on an ISA machine.  For all other machines, it has
@@ -134,7 +151,7 @@ Without this option,
 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.
-.PP
+
 The rtc device driver was new in Linux Release 2.
 .TP
 .B \-\-test
@@ -198,7 +215,42 @@ time Linux starts up, it will do so with the adjusted time from the Hardware
 Clock.  You can also use the program 
 .I 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
@@ -302,7 +354,11 @@ Another 24 hours goes by and you issue another
 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, 
+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
@@ -324,12 +380,12 @@ just before the
 at system startup time, and maybe periodically while the system is
 running via cron.
 .PP
-The format of the adjtime file is:
+The format of the adjtime file is, in ASCII:
 .PP
-Line 1: 3 numbers: 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
+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
 .I clock
 ).
 .PP
@@ -341,11 +397,51 @@ You can use an adjtime file that was previously used with the
 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
+.I 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
+.I 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 ENVIRONMENT VARIABLES
+.I TZ
+
 .SH FILES
 .I /etc/adjtime
+.I /usr/lib/zoneinfo/
 
 .SH SEE ALSO
-adjtimex(8), date(1), gettimeofday(2), settimeofday(2), crontab(1)
+adjtimex(8), date(1), gettimeofday(2), settimeofday(2), crontab(1),
+tzset(3)
 
 .SH AUTHORS
 Written By Bryan Henderson, September 1996 (bryanh@giraffe-data.com),
@@ -353,5 +449,3 @@ 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.  
-
-
index 643ccda5b86ef48af0f24439d78c8f6ae017da03..02302da29811823fcfc90491a601dd6f938939bb 100644 (file)
 #include <time.h>
 #include <sys/time.h>
 #include <sys/stat.h>
-#include <asm/io.h>
+#ifdef __i386__
+#include <asm/io.h>            /* for inb, outb */
+#endif
 #include <shhopt.h>
 #include "../version.h"
 
 #define MYNAME "hwclock"
-#define VERSION "2.2"
+#define VERSION "2.4"
 
 #define FLOOR(arg) ((arg >= 0 ? (int) arg : ((int) arg) - 1));
 
@@ -190,7 +192,6 @@ bool interrupts_enabled;
      need to be turned back on.
      */
 
-
 #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
@@ -658,17 +659,27 @@ synchronize_to_clock_tick(enum clock_access_method clock_access,
 
 
 
-static time_t
-mktime_tz(struct tm tm, const bool universal) {
+static void
+mktime_tz(struct tm tm, const bool universal, 
+          bool *valid_p, time_t *systime_p) {
 /*-----------------------------------------------------------------------------
   Convert a time in broken down format (hours, minutes, etc.) into standard
-  unix time (seconds into epoch).
+  unix time (seconds into epoch).  Return it as *systime_p.
 
   The broken down time is argument <tm>.  This broken down time is either in
   local time zone or UTC, depending on value of logical argument "universal".
   True means it is in UTC.
+
+  If the argument contains values that do not constitute a valid time,
+  and mktime() recognizes this, return *valid_p == false and
+  *systime_p undefined.  However, mktime() sometimes goes ahead and
+  computes a fictional time "as if" the input values were valid,
+  e.g. if they indicate the 31st day of April, mktime() may compute
+  the time of May 1.  In such a case, we return the same fictional
+  value mktime() does as *systime_p and return *valid_p == true.
+
 -----------------------------------------------------------------------------*/
-  time_t systime;   /* our eventual return value */
+  time_t mktime_result;  /* The value returned by our mktime() call */
   char *zone;       /* Local time zone name */
 
   /* We use the C library function mktime(), but since it only works on 
@@ -686,23 +697,31 @@ mktime_tz(struct tm tm, const bool universal) {
        */
     tzset();
   }
-  systime = mktime(&tm);
-  if (systime == -1) {
-    /* We don't expect this to happen.  Consider this a crash */
-    fprintf(stderr, "mktime() failed unexpectedly (rc -1).  Aborting.\n");
-    exit(2);
+  mktime_result = mktime(&tm);
+  if (mktime_result == -1) {
+    /* This apparently (not specified in mktime() documentation) means
+       the 'tm' structure does not contain valid values (however, not
+       containing valid values does _not_ imply mktime() returns -1).
+       */
+    *valid_p = FALSE;
+    *systime_p = 0;
+    if (debug)
+      printf("Invalid values in hardware clock: "
+             "%2d/%.2d/%.2d %.2d:%.2d:%.2d\n",
+             tm.tm_year, tm.tm_mon+1, tm.tm_mday,
+             tm.tm_hour, tm.tm_min, tm.tm_sec
+             );
+  } else {
+    *valid_p = TRUE;
+    *systime_p = mktime_result;
+    if (debug) 
+      printf("Hw clock time : %.2d:%.2d:%.2d = %d seconds since 1969\n", 
+             tm.tm_hour, tm.tm_min, tm.tm_sec, (int) *systime_p);
   }
-  
   /* now put back the original zone.  */
   if (zone) setenv("TZ", zone, TRUE);
   else unsetenv("TZ");
   tzset();
-
-  if (debug) 
-    printf("Hw clock time : %.2d:%.2d:%.2d = %d seconds since 1969\n", 
-           tm.tm_hour, tm.tm_min, tm.tm_sec, (int) systime);
-
-  return(systime);
 }
 
 
@@ -837,32 +856,28 @@ read_hardware_clock_isa(struct tm *tm) {
       tm->tm_mday = hclock_read_bcd(7);
       tm->tm_mon = hclock_read_bcd(8) - 1;
       tm->tm_year = hclock_read_bcd(9);
-      if (hclock_read_bcd(50) == 0) {
-        /* I suppose Linux could run on an old machine that doesn't implement
-           the Byte 50 century value, and that if it does, that machine puts
-           zero in Byte 50.  If so, this could could be useful, in that it
-           makes values 70-99 -> 1970-1999 and 00-69 -> 2000-2069.
-           */
-        if (hclock_read_bcd(9) >= 70) tm->tm_year = hclock_read_bcd(9);
-        else tm->tm_year = hclock_read_bcd(9) + 100;
-      } else {
-        tm->tm_year = hclock_read_bcd(50) * 100 + hclock_read_bcd(9) - 1900;
-        /* Note: Byte 50 contains centuries since A.D.  Byte 9 contains
-           years since beginning of century.  tm_year contains years
-           since 1900.  At least we _assume_ that's what tm_year
-           contains.  It is documented only as "year", and it could
-           conceivably be years since the beginning of the current
-           century.  If so, this code won't work after 1999.  
-           */
-      }
-      /* Unless the clock changed while we were reading, consider this 
-         a good clock read .
+      /* We don't use the century byte (Byte 50) of the Hardware Clock.
+         Here's why:  On older machines, it isn't defined.  In at least
+         one reported case, a machine puts some arbitrary value in that
+         byte.  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
+         21st century, otherwise it's the 20th.
          */
-      if (tm->tm_sec == hclock_read_bcd (0)) got_time = TRUE;
-        /* Yes, in theory we could have been running for 60 seconds and
-           the above test wouldn't work!
-           */
+
+        if (hclock_read_bcd(9) >= 37) tm->tm_year = hclock_read_bcd(9);
+        else tm->tm_year = hclock_read_bcd(9) + 100;
     }
+    /* Unless the clock changed while we were reading, consider this 
+       a good clock read .
+       */
+    if (tm->tm_sec == hclock_read_bcd (0)) got_time = TRUE;
+    /* Yes, in theory we could have been running for 60 seconds and
+       the above test wouldn't work!
+       */
   }
   tm->tm_isdst = -1;        /* don't know whether it's daylight */
 }
@@ -870,21 +885,25 @@ read_hardware_clock_isa(struct tm *tm) {
 
 
 static void
-read_hardware_clock(const enum clock_access_method method, struct tm *tm){
+read_hardware_clock(const enum clock_access_method method, 
+                    const bool universal, bool *valid_p, time_t *systime_p){
 /*----------------------------------------------------------------------------
   Read the hardware clock and return the current time via <tm> argument.
 
   Use the method indicated by <method> argument to access the hardware clock.
 -----------------------------------------------------------------------------*/
+  struct tm tm;
+
+
   switch (method) {
   case ISA:
-    read_hardware_clock_isa(tm);
+    read_hardware_clock_isa(&tm);
     break;
   case RTC_IOCTL:
-    read_hardware_clock_rtc_ioctl(tm);
+    read_hardware_clock_rtc_ioctl(&tm);
     break;
   case KD:
-    read_hardware_clock_kd(tm);
+    read_hardware_clock_kd(&tm);
     break;
   default:
     fprintf(stderr, 
@@ -893,7 +912,8 @@ read_hardware_clock(const enum clock_access_method method, struct tm *tm){
   }
   if (debug)
     printf ("Time read from Hardware Clock: %02d:%02d:%02d\n",
-            tm->tm_hour, tm->tm_min, tm->tm_sec);
+            tm.tm_hour, tm.tm_min, tm.tm_sec);
+  mktime_tz(tm, universal, valid_p, systime_p);
 }
 
 
@@ -994,14 +1014,13 @@ set_hardware_clock_isa(const struct tm new_broken_time,
   an ISA Hardware Clock.
 ----------------------------------------------------------------------------*/
   unsigned char save_control, save_freq_select;
-#ifdef __i386__
-  const bool interrupts_were_enabled = interrupts_enabled;
-#endif
 
   if (testing) 
     printf("Not setting Hardware Clock because running in test mode.\n");
   else {
 #ifdef __i386__
+    const bool interrupts_were_enabled = interrupts_enabled;
+
     __asm__ volatile ("cli");
     interrupts_enabled = FALSE;
 #endif
@@ -1220,21 +1239,30 @@ set_epoch(unsigned long epoch, const bool testing, int *retcode_p) {
 
 
 static void
-display_time(const time_t systime, const float sync_duration) {
+display_time(const bool hclock_valid, const time_t systime, 
+             const float sync_duration) {
 /*----------------------------------------------------------------------------
   Put the time "systime" on standard output in display format.
+  Except if hclock_valid == false, just tell standard output that we don't
+  know what time it is.
 
   Include in the output the adjustment "sync_duration".
 -----------------------------------------------------------------------------*/
-  char *ctime_now;  /* Address of static storage containing time string */
-
-  /* For some strange reason, ctime() is designed to include a newline
-     character at the end.  We have to remove that.
-     */
-  ctime_now = ctime(&systime);    /* Compute display value for time */
-  *(ctime_now+strlen(ctime_now)-1) = '\0';  /* Cut off trailing newline */
+  if (!hclock_valid)
+    fprintf(stderr, "The Hardware Clock registers contain values that are "
+            "either invalid (e.g. 50th day of month) or beyond the range "
+            "we can handle (e.g. Year 2095).\n");
+  else {
+    char *ctime_now;  /* Address of static storage containing time string */
 
-  printf("%s  %.6f seconds\n", ctime_now, -(sync_duration));
+    /* For some strange reason, ctime() is designed to include a newline
+       character at the end.  We have to remove that.
+       */
+    ctime_now = ctime(&systime);    /* Compute display value for time */
+    *(ctime_now+strlen(ctime_now)-1) = '\0';  /* Cut off trailing newline */
+    
+    printf("%s  %.6f seconds\n", ctime_now, -(sync_duration));
+  }
 }
 
 
@@ -1322,34 +1350,69 @@ interpret_date_string(const char *date_opt, time_t * const time_p) {
  
 
 static int 
-set_system_clock(const time_t newtime, const bool testing) {
+set_system_clock(const bool hclock_valid, const time_t newtime, 
+                 const bool testing) {
+/*----------------------------------------------------------------------------
+   Set the System Clock to time '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.
 
-  struct timeval tv;
+   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
+   the system time.
+
+   If 'testing' is true, don't actually update anything -- just say we 
+   would have.
+-----------------------------------------------------------------------------*/
   int retcode;  /* our eventual return code */
-  int rc;  /* local return code */
 
-  tv.tv_sec = newtime;
-  tv.tv_usec = 0;
-  
-  if (debug) {
-    printf( "Calling settimeofday:\n" );
-    printf( "\ttv.tv_sec = %ld, tv.tv_usec = %ld\n",
-           (long) tv.tv_sec, (long) tv.tv_usec );
-  }
-  if (testing) {
-    printf("Not setting system clock because running in test mode.\n");
-    retcode = 0;
+  if (!hclock_valid) {
+    fprintf(stderr,"The Hardware Clock does not contain a valid time, so "
+            "we cannot set the System Time from it.\n");
+    retcode = 1;
   } else {
-    rc = settimeofday(&tv, NULL);
-    if (rc != 0) {
-      if (errno == EPERM)
-        fprintf(stderr, "Must be superuser to set system clock.\n");
-      else
-        fprintf(stderr,
-                "settimeofday() failed, errno=%d:%s\n", 
-                errno, strerror(errno));
-      retcode = 1;
-    } else retcode = 0;
+    struct timeval tv;
+    int rc;  /* local return code */
+    
+    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'
+       */
+    
+    if (debug) {
+      printf( "Calling settimeofday:\n" );
+      printf( "\ttv.tv_sec = %ld, tv.tv_usec = %ld\n",
+             (long) tv.tv_sec, (long) tv.tv_usec );
+    }
+    if (testing) {
+      printf("Not setting system clock because running in test mode.\n");
+      retcode = 0;
+    } 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 ... */
+      rc = settimeofday(&tv, &tz);
+      if (rc != 0) {
+        if (errno == EPERM)
+          fprintf(stderr, "Must be superuser to set system clock.\n");
+        else
+          fprintf(stderr,
+                  "settimeofday() failed, errno=%d:%s\n", 
+                  errno, strerror(errno));
+        retcode = 1;
+      } else retcode = 0;
+    }
   }
   return(retcode);
 }
@@ -1358,7 +1421,7 @@ set_system_clock(const time_t newtime, const bool testing) {
 static void
 adjust_drift_factor(struct adjtime *adjtime_p,
                     const time_t nowtime, 
-                    const time_t hclocktime   ) {
+                    const bool hclock_valid, const time_t hclocktime   ) {
 /*---------------------------------------------------------------------------
   Update the drift factor in <*adjtime_p> to reflect the fact that the
   Hardware Clock was calibrated to <nowtime> and before that was set
@@ -1372,8 +1435,20 @@ adjust_drift_factor(struct adjtime *adjtime_p,
   We record in the adjtime file the time at which we last calibrated
   the clock so we can compute the drift rate each time we calibrate.
 
+  EXCEPT: if <hclock_valid> is false, assume Hardware Clock was not set
+  before to anything meaningful and regular adjustments have not been
+  done, so don't adjust the drift factor.
+
 ----------------------------------------------------------------------------*/
-  if ((hclocktime - adjtime_p->last_calib_time) >= 24 * 60 * 60) {
+  if (!hclock_valid) {
+    if (debug)
+      printf("Not adjusting drift factor because the Hardware Clock "
+             "previously contained garbage.\n");
+  } else if ((hclocktime - adjtime_p->last_calib_time) < 23 * 60 * 60) {
+    if (debug) 
+      printf("Not adjusting drift factor because it has been less than a "
+             "day since the last calibration.\n");
+  } else {
     const float factor_adjust = 
       ((float) (nowtime - hclocktime) 
        / (hclocktime - adjtime_p->last_calib_time))
@@ -1387,18 +1462,15 @@ adjust_drift_factor(struct adjtime *adjtime_p,
              (int) (hclocktime - adjtime_p->last_calib_time),
              adjtime_p->drift_factor,
              factor_adjust  );
-
+      
     adjtime_p->drift_factor += factor_adjust;
-  } else if (debug) 
-    printf("Not adjusting drift factor because it has been less than a "
-           "day since the last calibration.\n");
-
+  }
   adjtime_p->last_calib_time = nowtime;
   
   adjtime_p->last_adj_time = nowtime;
-
+  
   adjtime_p->not_adjusted = 0;
-
+    
   adjtime_p->dirty = TRUE;
 }
 
@@ -1507,7 +1579,8 @@ save_adjtime(const struct adjtime adjtime, const bool testing) {
 
 static void
 do_adjustment(struct adjtime *adjtime_p,
-              const time_t hclocktime, const struct timeval read_time,
+              const bool hclock_valid, const time_t hclocktime, 
+              const struct timeval read_time,
               const enum clock_access_method clock_access,
               const bool universal, const bool testing) {
 /*---------------------------------------------------------------------------
@@ -1515,10 +1588,14 @@ do_adjustment(struct adjtime *adjtime_p,
   necessary), and 2) updating the last-adjusted time in the adjtime
   structure.
 
+  Do not update anything if the Hardware Clock does not currently present
+  a valid time.
+
   arguments <factor> and <last_time> are current values from the adjtime
   file.
 
-  <hclocktime> is the current time set in the Hardware Clock.
+  <hclock_valid> means the Hardware Clock contains a valid time, and that
+  time is <hclocktime>.
 
   <read_time> is the current system time (to be precise, it is the system 
   time at the time <hclocktime> was read, which due to computational delay
@@ -1534,29 +1611,34 @@ do_adjustment(struct adjtime *adjtime_p,
   frequently.
 
 ----------------------------------------------------------------------------*/
-  int adjustment;
+  if (!hclock_valid) {
+    fprintf(stderr, "The Hardware Clock does not contain a valid time, "
+            "so we cannot adjust it.\n");
+  } else {
+    int adjustment;
     /* Number of seconds we must insert in the Hardware Clock */
-  float retro;   
+    float retro;   
     /* Fraction of second we have to remove from clock after inserting
        <adjustment> whole seconds.
        */
-  calculate_adjustment(adjtime_p->drift_factor,
-                       adjtime_p->last_adj_time,
-                       adjtime_p->not_adjusted,
-                       hclocktime,
-                       &adjustment, &retro,
-                       debug );
-  if (adjustment > 0 || adjustment < -1) {
-    set_hardware_clock_exact(hclocktime + adjustment, 
-                             time_inc(read_time, -retro),
-                             clock_access, universal, testing);
-    adjtime_p->last_adj_time = hclocktime + adjustment;
-    adjtime_p->not_adjusted = 0;
-    adjtime_p->dirty = TRUE;
-  } else 
-    if (debug) 
-      printf("Needed adjustment is less than one second, "
-             "so not setting clock.\n");
+    calculate_adjustment(adjtime_p->drift_factor,
+                         adjtime_p->last_adj_time,
+                         adjtime_p->not_adjusted,
+                         hclocktime,
+                         &adjustment, &retro,
+                         debug );
+    if (adjustment > 0 || adjustment < -1) {
+      set_hardware_clock_exact(hclocktime + adjustment, 
+                               time_inc(read_time, -retro),
+                               clock_access, universal, testing);
+      adjtime_p->last_adj_time = hclocktime + adjustment;
+      adjtime_p->not_adjusted = 0;
+      adjtime_p->dirty = TRUE;
+    } else 
+      if (debug) 
+        printf("Needed adjustment is less than one second, "
+               "so not setting clock.\n");
+  }
 }
 
 
@@ -1659,14 +1741,6 @@ manipulate_clock(const bool show, const bool adjust,
 ----------------------------------------------------------------------------*/
   struct adjtime adjtime;
     /* Contents of the adjtime file, or what they should be. */
-  struct tm tm;
-  time_t hclocktime;
-    /* The time the hardware clock had just after we synchronized to its
-       next clock tick when we started up.
-       */
-  struct timeval read_time; 
-    /* The time at which we read the Hardware Clock */
-
   int rc;  /* local return code */
   bool no_auth;  /* User lacks necessary authorization to access the clock */
 
@@ -1674,7 +1748,7 @@ manipulate_clock(const bool show, const bool adjust,
     rc = i386_iopl(3);
     if (rc != 0) {
       fprintf(stderr, MYNAME " is unable to get I/O port access.  "
-              "I.e. iopl(2) returned nonzero return code %d.\n"
+              "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);
@@ -1696,21 +1770,36 @@ manipulate_clock(const bool show, const bool adjust,
       synchronize_to_clock_tick(clock_access, retcode_p);  
         /* this takes up to 1 second */
       if (*retcode_p == 0) {
-        /* Get current time from Hardware Clock, in case we need it */
+        struct timeval read_time; 
+          /* The time at which we read the Hardware Clock */
+
+        bool hclock_valid;
+          /* The Hardware Clock gives us a valid time, or at least something
+             close enough to fool mktime().
+             */
+
+        time_t hclocktime;
+          /* The time the hardware clock had just after we
+             synchronized to its next clock tick when we started up.
+             Defined only if hclock_valid is true.
+             */
+        
         gettimeofday(&read_time, NULL);
-        read_hardware_clock(clock_access, &tm); 
-        hclocktime = mktime_tz(tm, universal);
+        read_hardware_clock(clock_access, universal, &hclock_valid, 
+                            &hclocktime); 
         
         if (show) {
-          display_time(hclocktime, time_diff(read_time, startup_time));
+          display_time(hclock_valid, hclocktime, 
+                       time_diff(read_time, startup_time));
           *retcode_p = 0;
         } else if (set) {
           set_hardware_clock_exact(set_time, startup_time, 
                                    clock_access, universal, testing);
-          adjust_drift_factor(&adjtime, set_time, hclocktime);
+          adjust_drift_factor(&adjtime, set_time, hclock_valid, hclocktime);
           *retcode_p = 0;
         } else if (adjust) {
-          do_adjustment(&adjtime, hclocktime, read_time, clock_access,
+          do_adjustment(&adjtime, hclock_valid, hclocktime, 
+                        read_time, clock_access,
                         universal, testing);
           *retcode_p = 0;
         } else if (systohc) {
@@ -1726,9 +1815,10 @@ manipulate_clock(const bool show, const bool adjust,
           set_hardware_clock_exact((time_t) reftime.tv_sec, reftime, 
                                    clock_access, universal, testing);
           *retcode_p = 0;
-          adjust_drift_factor(&adjtime, (time_t) reftime.tv_sec, hclocktime);
+          adjust_drift_factor(&adjtime, (time_t) reftime.tv_sec, hclock_valid, 
+                              hclocktime);
         } else if (hctosys) {
-          rc = set_system_clock(hclocktime, testing);
+          rc = set_system_clock(hclock_valid, hclocktime, testing);
           if (rc != 0) {
             printf("Unable to set system clock.\n");
             *retcode_p = 1;
@@ -1934,6 +2024,16 @@ main(int argc, char **argv, char **envp) {
 
   History of this program:
 
+  98.08.12 BJH   Version 2.4 
+
+  Don't use century byte from Hardware Clock.  Add comments telling why.
+
+
+  98.06.20 BJH   Version 2.3.
+
+  Make --hctosys set the kernel timezone from TZ environment variable
+  and/or /usr/lib/zoneinfo.  From Klaus Ripke (klaus@ripke.com).
+
   98.03.05 BJH.  Version 2.2.  
 
   Add --getepoch and --setepoch.  
index eceb0b71c17794053ffc26200a38227563e11991..c04b7fd4479a877541d559f1b886b1d28ee37951 100644 (file)
@@ -6,9 +6,24 @@
 #include <stdlib.h>
 #include <string.h>
 #include <errno.h>
+
+#include <sys/types.h>
+#include <sys/ipc.h>
 #include <sys/shm.h>
 #include <sys/msg.h>
 #include <sys/sem.h>
+#if defined (__GNU_LIBRARY__) && !defined(_SEM_SEMUN_UNDEFINED)
+/* union semun is defined by including <sys/sem.h> */
+#else
+/* according to X/OPEN we have to define it ourselves */
+union semun {
+       int val;
+       struct semid_ds *buf;
+       unsigned short int *array;
+       struct seminfo *__buf;
+};
+#endif
+
 
 int main(int argc, char **argv)
 {
index 9505aff550b5cad464d383a394cc62ad17017718..975bfd1a29e0a714c89858da549c18c194ad8fab 100644 (file)
 #include <time.h>
 #include <pwd.h>
 #include <grp.h>
-#define __KERNEL__
+#if 0
+#define __KERNEL__             /* yuk */
 #include <linux/linkage.h>
+#endif
+/* X/OPEN tells us to use <sys/{types,ipc,sem}.h> for semctl() */
+/* X/OPEN tells us to use <sys/{types,ipc,msg}.h> for msgctl() */
+/* X/OPEN tells us to use <sys/{types,ipc,shm}.h> for shmctl() */
+#include <sys/types.h>
+#include <sys/ipc.h>
 #include <sys/sem.h>
 #include <sys/msg.h>
 #include <sys/shm.h>
+/* The last arg of semctl is a union semun, but where is it defined?
+   X/OPEN tells us to define it ourselves, but until recently
+   Linux include files would also define it. */
+#if defined (__GNU_LIBRARY__) && !defined(_SEM_SEMUN_UNDEFINED)
+/* union semun is defined by including <sys/sem.h> */
+#else
+/* according to X/OPEN we have to define it ourselves */
+union semun {
+       int val;
+       struct semid_ds *buf;
+       unsigned short int *array;
+       struct seminfo *__buf;
+};
+#endif
 
+/* X/OPEN (Jan 1987) does not define fields key, seq in struct ipc_perm;
+   libc 4/5 does not mention struct ipc_term at all, but includes
+   <linux/ipc.h>, which defines a struct ipc_perm with such fields.
+   glibc-1.09 has no support for sysv ipc.
+   glibc 2 uses __key, __seq */
 #if defined (__GNU_LIBRARY__) && __GNU_LIBRARY__ > 1
 #define KEY __key
 #else
@@ -237,7 +263,7 @@ void do_shm (char format)
 
        default:
                printf ("------ Shared Memory Segments --------\n");
-               printf ("%-11s%-10s%-10s%-10s%-10s%-10s%-12s\n", "key","shmid",
+               printf ("%-10s%-10s%-10s%-10s%-10s%-10s%-12s\n", "key","shmid",
                        "owner","perms","bytes","nattch","status");
                break;
        }
index 3fef3395f8bec3fccbb0b522c1a1456a966376c0..88c6cbc1fd5a79c1c0f99fd6e240d2972d4919ac 100644 (file)
@@ -49,6 +49,13 @@ Not all keyboards have the rates mapped in the same way.
 Setting the repeat rate on the Gateway AnyKey keyboard does not work.  If
 someone with a Gateway figures out how to program the keyboard, please send
 mail to faith@cs.unc.edu.
+.PP
+The above description is for i386 machines, and writing to some io port
+won't work on other architectures. Nowadays
+.B kbdrate
+first tries if the KDKBDREP ioctl is available. If it is, it is used,
+otherwise the old method is applied.
+
 .SH FILES
 .I /etc/rc.local
 .br
index 07a7e40e586731830be568ecbf76c31e263eabf0..504429452507e35c28e9277e3fafb095c5afb3b9 100644 (file)
@@ -67,7 +67,7 @@ beats rebuilding the kernel!
 #include <sys/ioctl.h>
 #include <linux/version.h>
 #if LINUX_VERSION_CODE >= 131072
-/* Kd.h is not available with all linux versions.  131072 is equivalent
+/* kd.h is not available with all linux versions.  131072 is equivalent
    to linux 2.0.0 */
 #include <linux/kd.h>
 #endif
@@ -130,10 +130,15 @@ int main( int argc, char **argv )
    } else ioctl_possible = 1;
 
    if (ioctl_possible) {
-     kbdrep_s.rate  = 1000.0 / rate; /* convert cps to msec */
-     if (kbdrep_s.rate < 1) kbdrep_s.rate = 1;
+     if (rate == 0)                            /* switch repeat off */
+       kbdrep_s.rate = 0;
+     else
+       kbdrep_s.rate  = 1000.0 / rate;         /* convert cps to msec */
+     if (kbdrep_s.rate < 1)
+       kbdrep_s.rate = 1;
      kbdrep_s.delay = delay;
-     if (kbdrep_s.delay < 1) kbdrep_s.delay = 1;
+     if (kbdrep_s.delay < 1)
+       kbdrep_s.delay = 1;
      
      if (ioctl( 0, KDKBDREP, &kbdrep_s )) {
        perror( "ioctl(KDKBDREP)" );
@@ -192,7 +197,7 @@ int main( int argc, char **argv )
                            valid_rates[value & 0x1f] / 10.0,
                            valid_delays[ (value & 0x60) >> 5 ] );
 
-#ifdef KDKBREP
+#ifdef KDKBDREP
    }
 #endif
 
diff --git a/sys-utils/lpcntl.8 b/sys-utils/lpcntl.8
deleted file mode 100644 (file)
index 87bcd03..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-.\" Public Domain 1994 Rik Faith (faith@cs.unc.edu)
-.\" "
-.TH LPCNTL 8 "18 July 1994" "Linux 1.1" "Linux Programmer's Manual"
-.SH NAME
-lpcntl \- interface to line printer ioctl
-.SH SYNOPSIS
-.BI "lpcntl " device " [ " irq " ]"
-.SH DESCRIPTION
-.B lpcntl
-is used to manipulate the line printer driver.
-.PP
-.I device
-specifies a line printer device (e.g.,
-.IR /dev/lp1 ).
-.PP
-If
-.I irq
-is specified, then the line printer driver is set to use that IRQ.  If the
-.I irq
-is zero, then the polling driver is selected.  Only the super user may
-change the IRQ.
-.PP
-If no
-.I irq
-is specified, then
-.B lpcntl
-will report the interrupt number currently in use, or will report that the
-polling driver is currently being used.
-.SH AUTHOR
-Nigel Gamble (nigel@gate.net)
diff --git a/sys-utils/lpcntl.c b/sys-utils/lpcntl.c
deleted file mode 100644 (file)
index bf164a6..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Simple command interface to ioctl(fd, LPSETIRQ, irq).
- * Nigel Gamble (nigel@gate.net)
- * e.g.
- *     lpcntl /dev/lp1 7
- */
-
-#include <stdio.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <linux/lp.h>
-
-int
-main(int argc, char **argv)
-{
-       unsigned int irq;
-       int fd;
-       int ret;
-
-       if (argc < 2) {
-               fprintf(stderr, "usage: %s <lp device> [<irq>]\n", argv[0]);
-               exit(1);
-       }
-
-       fd = open(argv[1], O_RDONLY);
-       if (fd == -1) {
-               perror(argv[1]);
-               exit(1);
-       }
-
-       if (argc == 2) {
-               irq = ioctl(fd, LPGETIRQ);
-               if (irq == -1) {
-                       perror(argv[1]);
-                       exit(1);
-               }
-               if (irq)
-                       printf("%s using IRQ %d\n", argv[1], irq);
-               else
-                       printf("%s using polling\n", argv[1]);
-       } else {
-               irq = atoi(argv[2]);
-               ret = ioctl(fd, LPSETIRQ, irq);
-               if (ret == -1) {
-                       if (errno == EPERM)
-                               fprintf(stderr, "%s: only super-user can change the IRQ\n", argv[0]);
-                       else
-                               perror(argv[1]);
-                       exit(1);
-               }
-       }
-
-       return 0;
-}
similarity index 64%
rename from sys-utils/sln.1
rename to sys-utils/sln.8
index a8927193662a926809f6f6b0270ce91040287d12..f97683d476557f401665b08266ff4b10aeb4a902 100644 (file)
@@ -10,13 +10,14 @@ sln \- static ln
 symbolically links 
 .I dest
 to
-.I source
-It is statically linked, needing no dynamic linking at all.  This that
-sln is usefull to make symbolic links to dynamic libraries if the
+.IR source .
+It is statically linked, needing no dynamic linking at all.  Thus
+.B sln
+is useful to make symbolic links to dynamic libraries if the
 dynamic linking system for some reason is nonfunctional.
 .SH "SEE ALSO"
 .BR ln(1)
 .BR ldconfig(8)
 .BR ld.so(8)
-.SH AUTHOR
-Mike Parker and David MacKenzie.
+.\" .SH AUTHOR
+.\" Mike Parker and David MacKenzie.
index c657be72b98acbd843cfe88fcd55776459c6f05b..686418d61c4a24723a209e6832a9fb5ff2239237 100644 (file)
@@ -11,10 +11,6 @@ include ../MCONFIG
 MAN1=          col.1 colcrt.1 colrm.1 column.1 hexdump.1 more.1 rev.1 \
                ul.1
 
-ifeq "$(HAVE_STRINGS)" "no"
-MAN1:=$(MAN1) strings.1
-endif
-
 # Where to put binaries?
 # See the "install" rule for the links. . .
 
@@ -22,10 +18,6 @@ BIN=            more
 
 USRBIN=                col colcrt colrm column hexdump rev ul
 
-ifeq "$(HAVE_STRINGS)" "no"
-USRBIN:=$(USRBIN) strings
-endif
-
 # Where to put datebase files?
 
 USRLIB=                more.help
@@ -45,8 +37,7 @@ endif
 
 # Rules for hexdump
 
-hexdump: hexdump.o conv.o display.o hexsyntax.o odsyntax.o parse.o \
-       $(BSD)/getopt.o
+hexdump: hexdump.o conv.o display.o hexsyntax.o odsyntax.o parse.o
 hexdump.o: hexdump.c hexdump.h
 conv.o: conv.c hexdump.h
 display.o: display.c hexdump.h
@@ -56,13 +47,13 @@ parse.o: parse.c hexdump.h
 
 # Rules for everything else
 
-col: col.o $(BSD)/getopt.o
+col: col.o
 colcrt: colcrt.o
 colrm: colrm.o
-column: column.o $(BSD)/err.o
-more.o: more.c $(BSD)/pathnames.h
+column: column.o $(ERR_O)
+more.o: more.c $(LIB)/pathnames.h
 rev: rev.o
-strings: strings.o $(BSD)/getopt.o
+
 ifeq "$(HAVE_NCURSES)" "yes"
 more: more.o
 ul: ul.o
index a4d19bb5a7c950eeb04dac6fab0f6eab941b7d8f..f21f7692779e9793d003a2fdab45c078e922477f 100644 (file)
@@ -64,10 +64,11 @@ char        printall;
 char   *progname;
 FILE   *f;
 
-int main(int argc, char **argv)
+int
+main(int argc, char **argv)
 {
-       register c;
-       register char *cp, *dp;
+       int c;
+       char *cp, *dp;
 
        argc--;
        progname = *argv++;
index 3051c866ce6647003826b8c91c0abcc773dc172b..f189e25d262c5d79ae4a7343b0b8c9f2b6efb16f 100644 (file)
@@ -40,9 +40,10 @@ COLRM removes unwanted columns from a file
 
 int getn(char *ap);
 
-int main(int argc, char **argv)
+int
+main(int argc, char **argv)
 {
-       register c, ct, first, last;
+       register int c, ct, first, last;
 
        first = 0;
        last = 0;
index 09f52ebba36d3da543dbc2d28cd4db40db0a95ba..4ae9522ef735b1721e8fde2d4f9b9b53381304eb 100644 (file)
@@ -164,7 +164,6 @@ r_columnate()
        int base, chcnt, cnt, col, endcol, numcols, numrows, row;
 
        maxlength = (maxlength + TAB) & ~(TAB - 1);
-       /* This could be 0 */
        numcols = termwidth / maxlength;
        if (!numcols) 
          numcols = 1;
index 6e0763169dcf47d4e7e657fe9c0732641eeaff84..24045472d6c67f301b8e47d4a962e0f5b5cdccea 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1980 Regents Of the University of California.
+ * Copyright (C) 1980 The Regents of the University of California.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms are permitted
@@ -49,6 +49,7 @@
 #include <curses.h>
 #endif
 #include <term.h>
+#include <locale.h>
 
 #define HELPFILE       "/usr/lib/more.help"
 #define VI             "/usr/bin/vi"
@@ -93,6 +94,8 @@ int  get_line(register FILE *f, int *length);
 void prbuf (register char *s, register int n);
 int  xprintf (char *fmt, ...);
 void execute (char *filename, char *cmd, ...);
+void errwrite (char *txt);
+void errwrite1 (char *sym);
 
 #define TBUFSIZ        1024
 #define LINSIZ 256
@@ -149,7 +152,7 @@ int         soglitch;       /* terminal has standout mode glitch */
 int            ulglitch;       /* terminal has underline mode glitch */
 int            pstate = 0;     /* current UL state */
 char           *getenv();
-static         magic();
+static int     magic();
 struct {
     long chrctr, line;
 } context, screen_start;
@@ -165,7 +168,7 @@ int main(int argc, char **argv) {
     FILE       *f;
     char       *s;
     char       *p;
-    char       ch;
+    int                ch;
     int                left;
     int                prnames = 0;
     int                initopt = 0;
@@ -183,6 +186,7 @@ int main(int argc, char **argv) {
 
     nfiles = argc;
     fnames = argv;
+    setlocale(LC_ALL, "");
     initterm ();
     nscroll = Lpp/2 - 1;
     if (nscroll <= 0)
@@ -286,8 +290,7 @@ int main(int argc, char **argv) {
            if (firstf) setjmp (restore);
            if (firstf) {
                firstf = 0;
-               if (srchopt)
-               {
+               if (srchopt) {
                    search (initbuf, f, 1);
                    if (noscroll)
                        left--;
@@ -300,11 +303,12 @@ int main(int argc, char **argv) {
                left = command (fnames[fnum], f);
            }
            if (left != 0) {
-               if ((noscroll || clearit) && (file_size != LONG_MAX))
+               if ((noscroll || clearit) && (file_size != LONG_MAX)) {
                    if (clreol)
                        home ();
                    else
                        doclear ();
+               }
                if (prnames) {
                    if (bad_so)
                        erasep (0);
@@ -434,21 +438,23 @@ magic(f, fs)
        FILE *f;
        char *fs;
 {
-       struct exec ex;
+       char twobytes[2];
 
-       if (fread(&ex, sizeof(ex), 1, f) == 1)
-               switch(ex.a_info) {
-               case OMAGIC:
-               case NMAGIC:
-               case ZMAGIC:
+       if (fread(twobytes, 2, 1, f) == 1) {
+               switch(twobytes[0] + (twobytes[1]<<8)) {
+               case OMAGIC:    /* 0407 */
+               case NMAGIC:    /* 0410 */
+               case ZMAGIC:    /* 0413 */
                case 0405:
                case 0411:
                case 0177545:
+               case 0x457f:            /* simple ELF detection */
                        xprintf("\n******** %s: Not a text file ********\n\n", fs);
                        (void)fclose(f);
                        return(1);
                }
-       (void)fseek(f, 0L, L_SET);              /* rewind() not necessary */
+       }
+       (void)fseek(f, 0L, SEEK_SET);           /* rewind() not necessary */
        return(0);
 }
 
@@ -547,7 +553,7 @@ void onquit()
            Pause++;
     }
     else if (!dum_opt && notell) {
-       write (2, "[Use q or Q to quit]", 20);
+       errwrite("[Use q or Q to quit]");
        promptlen += 20;
        notell = 0;
     }
@@ -597,7 +603,7 @@ void end_it ()
        fflush (stdout);
     }
     else
-       write (2, "\n", 1);
+       errwrite("\n");
     _exit(0);
 }
 
@@ -682,7 +688,7 @@ void scanstr (int n, char *str)
     *sptr = '\0';
 }
 
-static char my_bell = ctrl('G');
+#define ringbell()     errwrite("\007");
 
 #ifdef undef
 strlen (s)
@@ -750,7 +756,7 @@ char *filename;
        fflush(stdout);
     }
     else
-       write (2, &my_bell, 1);
+       ringbell();
     inwait++;
 }
 
@@ -787,7 +793,7 @@ int get_line(register FILE *f, int *length)
            break;
        }
        *p++ = c;
-       if (c == '\t')
+       if (c == '\t') {
            if (!hardtabs || (column < promptlen && !hard)) {
                if (hardtabs && eraseln && !dumb) {
                    column = 1 + (column | 7);
@@ -805,9 +811,9 @@ int get_line(register FILE *f, int *length)
            }
            else
                column = 1 + (column | 7);
-       else if (c == '\b' && column > 0)
+       } else if (c == '\b' && column > 0) {
            column--;
-       else if (c == '\r') {
+       else if (c == '\r') {
            int next = Getc(f);
            if (next == '\n') {
                p--;
@@ -816,18 +822,16 @@ int get_line(register FILE *f, int *length)
            }
            Ungetc(next,f);
            column = 0;
-       }
-       else if (c == '\f' && stop_opt) {
+       } else if (c == '\f' && stop_opt) {
                p[-1] = '^';
                *p++ = 'L';
                column += 2;
                Pause++;
-       }
-       else if (c == EOF) {
+       } else if (c == EOF) {
            *length = p - Line;
            return (column);
        }
-       else if (c >= ' ' && c != RUBOUT)
+       else if (isprint(c))
            column++;
        if (column >= Mcol && fold_opt) break;
        c = Getc (f);
@@ -988,7 +992,7 @@ int command (char *filename, register FILE *f)
 {
     register int nlines;
     register int retval = 0;
-    register char c;
+    register int c;
     char colonch;
     FILE *helpf;
     int done;
@@ -1030,7 +1034,7 @@ int command (char *filename, register FILE *f)
                register int initline;
 
                if (no_intty) {
-                   write(2, &my_bell, 1);
+                   ringbell();
                    return (-1);
                }
 
@@ -1122,7 +1126,7 @@ int command (char *filename, register FILE *f)
                ret (dlines);
            }
            else {
-               write (2, &my_bell, 1);
+               ringbell();
                break;
            }
        case '\'':
@@ -1134,7 +1138,7 @@ int command (char *filename, register FILE *f)
                ret (dlines);
            }
            else {
-               write (2, &my_bell, 1);
+               ringbell();
                break;
            }
        case '=':
@@ -1151,12 +1155,12 @@ int command (char *filename, register FILE *f)
            promptlen = 1;
            fflush (stdout);
            if (lastp) {
-               write (2,"\r", 1);
+               errwrite ("\r");
                search (NULL, f, nlines);       /* Use previous r.e. */
            }
            else {
                ttyin (cmdbuf, sizeof(cmdbuf)-2, '/');
-               write (2, "\r", 1);
+               errwrite("\r");
                search (cmdbuf, f, nlines);
            }
            ret (dlines-1);
@@ -1195,7 +1199,7 @@ int command (char *filename, register FILE *f)
                fflush (stdout);
            }
            else
-               write (2, &my_bell, 1);
+               ringbell();
            break;
        }
        if (done) break;
@@ -1243,7 +1247,7 @@ int colon (char *filename, int cmd, int nlines)
                return (0);
        case 'p':
                if (no_intty) {
-                       write (2, &my_bell, 1);
+                       ringbell();
                        return (-1);
                }
                putchar ('\r');
@@ -1259,7 +1263,7 @@ int colon (char *filename, int cmd, int nlines)
        case 'Q':
                end_it ();
        default:
-               write (2, &my_bell, 1);
+               ringbell();
                return (-1);
        }
 }
@@ -1276,7 +1280,7 @@ int number(char *cmd)
        i = 0; ch = otty.c_cc[VKILL];
        for (;;) {
                ch = readch ();
-               if (ch >= '0' && ch <= '9')
+               if (isdigit(ch))
                        i = i*10 + ch - '0';
                else if (ch == otty.c_cc[VKILL])
                        i = 0;
@@ -1306,7 +1310,7 @@ void do_shell (char *filename)
                }
        }
        fflush (stdout);
-       write (2, "\n", 1);
+       errwrite("\n");
        promptlen = 0;
        shellp = 1;
        execute (filename, shell, shell, "-c", shell_line, 0);
@@ -1337,7 +1341,7 @@ void search(char buf[], FILE *file, register int n)
        line1 = Ftell (file);
        rdline (file);
        lncount++;
-       if ((rv = re_exec (Line)) == 1)
+       if ((rv = re_exec (Line)) == 1) {
                if (--n == 0) {
                    if (lncount > 3 || (lncount > 1 && no_intty))
                    {
@@ -1349,29 +1353,31 @@ void search(char buf[], FILE *file, register int n)
                    if (!no_intty) {
                        Currline -= (lncount >= 3 ? 3 : lncount);
                        Fseek (file, line3);
-                       if (noscroll)
+                       if (noscroll) {
                            if (clreol) {
                                home ();
                                cleareol ();
                            }
                            else
                                doclear ();
+                       }
                    }
                    else {
                        kill_line ();
-                       if (noscroll)
+                       if (noscroll) {
                            if (clreol) {
                                home ();
                                cleareol ();
                            }
                            else
                                doclear ();
+                       }
                        pr (Line);
                        putchar ('\n');
                    }
                    break;
                }
-       else if (rv == -1)
+       else if (rv == -1)
            error ("Regular expression botch");
     }
     if (feof (file)) {
@@ -1435,7 +1441,7 @@ void execute (char * filename, char * cmd, ...)
            va_end(argp);       /* balance {}'s for some UNIX's */
        
            execv (cmd, args);
-           write (2, "exec failed\n", 12);
+           errwrite("exec failed\n");
            exit (1);
        }
        if (id > 0) {
@@ -1449,7 +1455,7 @@ void execute (char * filename, char * cmd, ...)
            if (catch_susp)
                signal(SIGTSTP, onsusp);
        } else
-           write(2, "can't fork\n", 11);
+           errwrite("can't fork\n");
        set_tty ();
        pr ("------------------------\n");
        prompt (filename);
@@ -1460,7 +1466,7 @@ void execute (char * filename, char * cmd, ...)
 
 void skiplns (register int n, register FILE *f)
 {
-    register char c;
+    register int c;
 
     while (n > 0) {
        while ((c = Getc (f)) != '\n')
@@ -1636,22 +1642,23 @@ int readch ()
        extern int errno;
 
        errno = 0;
-       if (read (2, &ch, 1) <= 0)
+       if (read (2, &ch, 1) <= 0) {
                if (errno != EINTR)
                        end_it();
                else
                        ch = otty.c_cc[VKILL];
+       }
        return (ch);
 }
 
-static char BS = '\b';
+static char *BS = "\b";
 static char *BSB = "\b \b";
-static char CARAT = '^';
+static char *CARAT = "^";
 #define ERASEONECHAR \
     if (docrterase) \
-       write (2, BSB, sizeof(BSB)); \
+       errwrite(BSB); \
     else \
-       write (2, &BS, sizeof(BS));
+       errwrite(BS);
 
 void ttyin (char buf[], register int nmax, char pchar)
 {
@@ -1698,7 +1705,7 @@ void ttyin (char buf[], register int nmax, char pchar)
                    erasep (1);
                else if (docrtkill)
                    while (promptlen-- > 1)
-                       write (2, BSB, sizeof(BSB));
+                       errwrite(BSB);
                promptlen = 1;
            }
            sptr = buf;
@@ -1714,12 +1721,12 @@ void ttyin (char buf[], register int nmax, char pchar)
        *sptr++ = ch;
        if ((ch < ' ' && ch != '\n' && ch != ESC) || ch == RUBOUT) {
            ch += ch == RUBOUT ? -0100 : 0100;
-           write (2, &CARAT, 1);
+           errwrite(CARAT);
            promptlen++;
        }
        cbuf = ch;
        if (ch != '\n' && ch != ESC) {
-           write (2, &cbuf, 1);
+           errwrite1(&cbuf);
            promptlen++;
        }
        else
@@ -1778,14 +1785,24 @@ void show (register char ch)
 
     if ((ch < ' ' && ch != '\n' && ch != ESC) || ch == RUBOUT) {
        ch += ch == RUBOUT ? -0100 : 0100;
-       write (2, &CARAT, 1);
+       errwrite(CARAT);
        promptlen++;
     }
     cbuf = ch;
-    write (2, &cbuf, 1);
+    errwrite1(&cbuf);
     promptlen++;
 }
 
+void errwrite (char *txt)
+{
+    write (fileno(stderr), txt, strlen(txt));
+}
+
+void errwrite1 (char *sym)
+{
+    write (fileno(stderr), sym, 1);
+}
+
 void error (char *mess)
 {
     if (clreol)
@@ -1809,6 +1826,8 @@ void error (char *mess)
 void set_tty ()
 {
        otty.c_lflag &= ~(ICANON|ECHO);
+       otty.c_cc[VMIN] = 1;    /* read at least 1 char */
+       otty.c_cc[VTIME] = 0;   /* no timeout */
        stty(fileno(stderr), &otty);
 }
 
@@ -1826,12 +1845,14 @@ void reset_tty ()
        pstate = 0;
     }
     otty.c_lflag |= ICANON|ECHO;
+    otty.c_cc[VMIN] = savetty0.c_cc[VMIN];
+    otty.c_cc[VTIME] = savetty0.c_cc[VTIME];
     stty(fileno(stderr), &savetty0);
 }
 
 void rdline (register FILE *f)
 {
-    register char c;
+    register int  c;
     register char *p;
 
     p = Line;
index f10d224567152de90554abc3ec8ca6ad7618254f..8da3b3f7cc7e9241f7f3c54ca74b4c8f3dde75aa 100644 (file)
@@ -41,6 +41,7 @@
 #include <string.h>            /* for bzero() */
 #include <term.h>              /* for setupterm() */
 #include <stdlib.h>            /* for getenv() */
+#include <limits.h>            /* for INT_MAX */
 
 void filter(FILE *f);
 void flushln(void);
@@ -52,6 +53,7 @@ void reverse(void);
 void initinfo(void);
 void outc(int c);
 void setmode(int newmode);
+void setcol(int newcol);
 
 #define        IESC    '\033'
 #define        SO      '\016'
@@ -59,7 +61,6 @@ void setmode(int newmode);
 #define        HFWD    '9'
 #define        HREV    '8'
 #define        FREV    '7'
-#define        MAXBUF  512
 
 #define        NORMAL  000
 #define        ALTSET  001     /* Reverse */
@@ -67,6 +68,7 @@ void setmode(int newmode);
 #define        SUBSC   004     /* Dim | Ul */
 #define        UNDERL  010     /* Ul */
 #define        BOLD    020     /* Bold */
+#define        INITBUF 512
 
 int    must_use_uc, must_overstrike;
 char   *CURS_UP, *CURS_RIGHT, *CURS_LEFT,
@@ -78,7 +80,8 @@ struct        CHAR    {
        char    c_char;
 } ;
 
-struct CHAR    obuf[MAXBUF];
+struct CHAR    *obuf;
+int    obuflen;                /* Tracks number of elements in obuf. */
 int    col, maxcol;
 int    mode;
 int    halfpos;
@@ -150,23 +153,20 @@ int main(int argc, char **argv)
 
 void filter(FILE *f)
 {
-       register c;
+       int c;
 
        while ((c = getc(f)) != EOF) switch(c) {
 
        case '\b':
-               if (col > 0)
-                       col--;
+               setcol(col - 1);
                continue;
 
        case '\t':
-               col = (col+8) & ~07;
-               if (col > maxcol)
-                       maxcol = col;
+               setcol((col+8) & ~07);
                continue;
 
        case '\r':
-               col = 0;
+               setcol(0);
                continue;
 
        case SO:
@@ -224,9 +224,7 @@ void filter(FILE *f)
                else
                        obuf[col].c_char = '_';
        case ' ':
-               col++;
-               if (col > maxcol)
-                       maxcol = col;
+               setcol(col + 1);
                continue;
 
        case '\n':
@@ -251,9 +249,7 @@ void filter(FILE *f)
                        obuf[col].c_mode |= BOLD|mode;
                else
                        obuf[col].c_mode = mode;
-               col++;
-               if (col > maxcol)
-                       maxcol = col;
+               setcol(col + 1);
                continue;
        }
        if (maxcol)
@@ -262,8 +258,8 @@ void filter(FILE *f)
 
 void flushln()
 {
-       register lastmode;
-       register i;
+       int lastmode;
+       int i;
        int hadmodes = 0;
 
        lastmode = NORMAL;
@@ -274,9 +270,9 @@ void flushln()
                        lastmode = obuf[i].c_mode;
                }
                if (obuf[i].c_char == '\0') {
-                       if (upln)
+                       if (upln) {
                                PRINT(CURS_RIGHT);
-                       else
+                       else
                                outc(' ');
                } else
                        outc(obuf[i].c_char);
@@ -361,21 +357,30 @@ void iattr()
 
 void initbuf()
 {
+       if (obuf == NULL) {     /* First time. */
+               obuflen = INITBUF;
+               obuf = malloc(sizeof(struct CHAR) * obuflen);
+               if (obuf == NULL) {
+                       fprintf(stderr, "Unable to allocate buffer.\n");
+                       exit(1);
+               }
+       }
 
-       bzero((char *)obuf, sizeof (obuf));     /* depends on NORMAL == 0 */
-       col = 0;
+       /* assumes NORMAL == 0 */
+       bzero((char *)obuf, sizeof(struct CHAR) * obuflen);
+       setcol(0);
        maxcol = 0;
        mode &= ALTSET;
 }
 
 void fwd()
 {
-       register oldcol, oldmax;
+       int oldcol, oldmax;
 
        oldcol = col;
        oldmax = maxcol;
        flushln();
-       col = oldcol;
+       setcol(oldcol);
        maxcol = oldmax;
 }
 
@@ -390,7 +395,7 @@ void reverse()
 
 void initinfo()
 {
-       char *getenv(), *tigetstr();
+       char *tigetstr();
 
        CURS_UP =               tigetstr("cuu1");
        CURS_RIGHT =            tigetstr("cuf1");
@@ -495,3 +500,40 @@ void setmode(int newmode)
        }
        curmode = newmode;
 }
+
+
+
+
+void setcol(int newcol)
+{
+       col = newcol;
+
+       if (col < 0)
+               col = 0;
+       else if (col > maxcol) {
+               maxcol = col;
+
+               /* If col >= obuflen, expand obuf until obuflen > col. */
+               while (col >= obuflen) {
+                       /* Paranoid check for obuflen == INT_MAX. */
+                       if (obuflen == INT_MAX) {
+                               fprintf(stderr,
+                                       "Input line too long.\n");
+                               exit(1);
+                       }
+
+                       /* Similar paranoia: double only up to INT_MAX. */
+                       obuflen = ((INT_MAX / 2) < obuflen)
+                               ? INT_MAX
+                               : obuflen * 2;
+
+                       /* Now we can try to expand obuf. */
+                       obuf = realloc(obuf, sizeof(struct CHAR) * obuflen);
+                       if (obuf == NULL) {
+                               fprintf(stderr,
+                                       "Out of memory when growing buffer.\n");
+                               exit(1);
+                       }
+               }
+       }
+}
diff --git a/uio.h-diff b/uio.h-diff
deleted file mode 100644 (file)
index 48be527..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
---- /usr/include/sys/uio.h~    Sun Jan 24 20:02:24 1993
-+++ /usr/include/sys/uio.h     Thu Oct 12 12:29:00 1995
-@@ -32,6 +32,7 @@
- /* Structure describing a section of memory.  */
-+#if 0
- struct iovec
-   {
-     /* Starting address.  */
-@@ -39,6 +40,9 @@
-     /* Length in bytes.  */
-     size_t iov_len;
-   };
-+#else
-+#include <linux/uio.h>
-+#endif
- __BEGIN_DECLS
diff --git a/util-linux-2.1.Announce b/util-linux-2.1.Announce
deleted file mode 100644 (file)
index 0906617..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-
-util-linux-2.1.tar.gz     (source distribution)
-util-linux-2.1.bin.tar.gz (binary distribution)
-
-    WARNING: THIS COLLECTION DOES *NOT* SUPPORT SHADOW PASSWORDS.
-
-    WARNING: THIS COLLECTION DOES *NOT* SUPPORT SYSTEM V INITTAB.
-
-    WARNING: USE GNU TAR -- OTHER TARS WILL FAIL SILENTLY!
-
-    WARNING: DO *NOT* INSTALL WITHOUT THINKING.
-
-    WARNING: *READ* the util-linux-2.1.bin.Notes file *BEFORE* and *AFTER*
-             installation: there are a few links you must make by hand.
-
-    This is a collection of many assorted utilities for Linux.  Some are
-    system utilities that are not easily available anywhere elsewhere
-    (e.g., mkfs.minix, mkswap); others are BSD ports of common utilities
-    that are not yet contained in any FSF package (e.g., col); others are
-    non-System-V alternatives to common utilities (e.g., simpleinit,
-    agetty, login, passwd).
-
-    The arrangement, as nearly as I can determine, conforms to the Linux
-    Filesystem Structure, Interim Release 1.1, October 9, 1994, with *NO*
-    exceptions.  A copy of the standards document can be found at
-    tsx-11.mit.edu:/pub/linux/docs/linux-standards/fsstnd/*.
-
-    Many people provided patches and suggestions.  I deeply appreciate
-    this.
-
-
-HIGHLIGHTS for version 2.1:
-
-1) Directory structure rearrange, with configuration support for those who
-   use shadow passwords and System V init (no support is provided for these
-   things, but your utilities won't get overwritten if you do a "make
-   install" after you properly edit MCONFIG).
-2) fdisk and cfdisk should work as expected with 2GB+ disk drives
-3) As usual, lots of stuff was updated and added, including mount, vipw,
-   readprofile
-4) Some stuff was also deleted, and can now be found elsewhere:
-    fsck wrapper: tsx-11.mit.edu:/pub/linux/ALPHA/ext2fs/e2fsprogs*
-    pwd, su: prep.ai.mit.edu:/pub/gnu/sh-utils*
-    ed: prep.ai.mit.edu:/pub/gnu/ed*
-    od: prep.ai.mit.edu:/pub/gnu/textutils*
-    uudecode/uuencode: prep.ai.mit.edu:/pub/gnu/sharutils*
-    bdflush/update: ftp.funet.fi:/pub/OS/Linux/PEOPLE/Linus/v1.1/bdflush*
-
diff --git a/util-linux-2.1.bin.Notes b/util-linux-2.1.bin.Notes
deleted file mode 100644 (file)
index a2ac394..0000000
+++ /dev/null
@@ -1,549 +0,0 @@
-util-linux: Miscellaneous utilities for Linux
-%n util-linux
-%v 2.1
-%c *
-%l *
-%b *
-%d *
-%f ftp.cs.unc.edu:/pub/users/faith/linux/utils
-%t util-linux-2.1.tar.gz
-%w utils
-%%
-# These lines describe an automated build procedure, please ignore them.
-%setup
-make
-%doc COPYING.GPL COPYING.UCB
-%doc ./time/README.time ./disk-utils/README.cfdisk
-%doc ./disk-utils/README.fdisk ./disk-utils/README.bootutils-0.1
-%doc ./sys-utils/README.setserial ./makedev-1.4.1/README.MAKEDEV-C
-%doc ./misc-utils/README.script ./misc-utils/README.hostname
-%doc ./misc-utils/README.namei ./misc-utils/README.cal
-%doc ./misc-utils/README1.namei ./text-utils/README.col
-%doc ./mount/README.mount ./selection/README.selection
-%doc ./login-utils/README.getty ./login-utils/README.admutil
-%doc ./login-utils/README.poeigl
-%doc util-linux-$VERSION.Announce util-linux-$VERSION.lsm
-cp -a $BUILDDIR/$NAME-$VERSION/example.files /usr/doc/$WHERE/$NAME-$VERSION
-* rm -rf /usr/lib/zoneinfo
-* make install
-%i set -x
-%i /usr/sbin/zic -l US/Eastern
-%i /usr/sbin/zic -p America/New_York
-%i set +x
-%i echo 'WARNING: Check time zone!  (If necessary, change with zic).'
-%i echo 'WARNING: Check /etc/rc for initalization of /var/adm/utmp'
-%i echo 'WARNING: /etc/rc should run /sbin/update, *NOT* /sbin/bdflush'
-exit
-# Please ignore the previous lines. . .
-# The informative part of the notes file starts here:
-
-WARNING: THE PROGRAMS IN THIS SUITE DO *NOT* SUPPORT SHADOW PASSWORD FILES!
-
-WARNING: THIS COLLECTION DOES *NOT* SUPPORT SYSTEM V INITTAB.
-
-WARNING: USE GNU TAR -- OTHER TARS WILL FAIL SILENTLY!
-
-WARNING: DO *NOT* INSTALL WITHOUT THINKING.
-
-WARNING: Read the util-linux-2.1.bin.Notes file *BEFORE* and *AFTER*
-         installation: there are a few links you must make by hand.
-
-WARNING: The agetty, simpleinit, login, passwd, and other programs in this
-         package are *NOT* System V compliant.  These utilities are meant
-         to be used by people who build their own systems.  If you are not
-         a wizard, do *NOT* blindly install these utilities: they could
-         prevent you from logging into your system.  Have a boot floppy
-         ready, especially if you don't know what you are doing.
-
-WARNING: The binary distribution was tarred using GNU TAR AND THE -S OPTION!
-         This means that holes will be preserved, but that ONLY GNU TAR
-         WILL WORK ON THE BINARY DISTRIBUTION (in fact, other, inferior,
-         tar programs will fail silently).  YOU HAVE BEEN WARNED!
-
-WARNING: localtime and posixtime default to US/Eastern -- change these now.
-
-
-
-To install from the binary distribution:
-
-1) Get binary distribution (see the .lsm file for locations)
-2) cd /
-3) gtar zpxvf util-linux-2.1.bin.tar.gz
-   (or: pms -i util-linux-2.1.bin.tar.gz)
-4) *IF* you want to use agetty and simpleinit, then make softlinks from
-   /sbin/init to simpleinit and from /sbin/getty to agetty, but make sure
-   that your /etc/inittab is set up right (this is *NOT* the System V
-   compatible init!), or you will be hosed.
-5) Run zic -l and/or zic -p to set your timezone.  The distribution is set
-   up to use /usr/lib/zoneinfo/US/Eastern as the default.  This was
-   installed with "zic -l US/Eastern"
-6) Remove all the old binaries from previous locations.
-
-
-
-To install from source:
-
-1) Get source distribution (see the .lsm file for locations)
-2) Untar util-linux-2.1.tar.gz in /usr/src
-3) cd util-linux-2.1
-4) Edit MCONFIG:
-
-   If you use the shadow password suite and do _not_ want to install
-   programs like login and passwd that do not support shadow passwords,
-   then set HAVE_SHADOW to yes
-
-   If you use the System V init suite and do _not_ want to install programs
-   like agetty, simpleinit, and shutdown, then set HAVE_SYSVINIT to yes
-
-   If you don't like the compile-time options or the directories, then
-   change them.  Note that you also can say something like "make OPT=-g
-   LDFLAGS=" in order to make a complete debugging version without editing
-   the MCONFIG at all.
-
-5) make
-6) make install
-7) If you want to use simpleinit and agetty, then make softlinks from
-   /sbin/init to simpleinit and from /sbin/getty to agetty, but make sure
-   that your /etc/inittab is set up right (this is *NOT* the System V
-   compatible init!), or you will be hosed.  If you are using the SysV
-   init and/or some other getty, they you can keep using those.
-8) Run zic -l and/or zic -p to set your timezone.  The distribution is set
-   up to use /usr/lib/zoneinfo/US/Eastern as the default.  This was
-   installed with "zic -l US/Eastern"
-9) Remove all the old binaries from previous locations.
-
-
-
-HIGHLIGHTS for version 2.1:
-
-1) Directory structure rearrange, with configuration support for those who
-   use shadow passwords and System V init (no support is provided for these
-   things, but your utilities won't get overwritten if you do a "make
-   install" after you properly edit MCONFIG).
-2) fdisk and cfdisk should work as expected with 2GB+ disk drives
-3) As usual, lots of stuff was updated and added, including mount, vipw,
-   readprofile
-4) Some stuff was also deleted, and can now be found elsewhere:
-    fsck wrapper: tsx-11.mit.edu:/pub/linux/ALPHA/ext2fs/e2fsprogs*
-    pwd, su: prep.ai.mit.edu:/pub/gnu/sh-utils*
-    ed: prep.ai.mit.edu:/pub/gnu/ed*
-    od: prep.ai.mit.edu:/pub/gnu/textutils*
-    uudecode/uuencode: prep.ai.mit.edu:/pub/gnu/sharutils*
-    bdflush/update: ftp.funet.fi:/pub/OS/Linux/PEOPLE/Linus/v1.1/bdflush*
-
-
-
-PARTIAL HISTORY OF UTIL-LINUX:
-
-bsd:
-    Nothing in this directory gets installed, but some BSD programs need
-    this support:
-        err.c: 8.1 (Berkeley) 6/4/93
-        err.h: 8.1 (Berkeley) 6/2/93
-        getopt.c: 4.13 (Berkeley) 2/23/91
-        pathnames.h: 5.3 (Berkeley) 5/9/89 with extensive modifications for
-                     Linux
-
-disk-utils:
-    cfdisk: 0.8 BETA (>2GB) from Kevin E. Martin (martin@cs.unc.edu) with
-            modifications for disks > 2GB.
-            ftp.cs.unc.edu:/pub/users/martin/linux/cfdisk-0.8.tar.gz
-    fdformat: Werner Almesberger (almesber@nessie.cs.id.ethz.ch), with
-              modifications by Marcel Mol (marcel@dutecad.et.tudelft.nl)).
-              Later, updated with a September 1992 version by Werner.
-    fdisk: A. V. Le Blanc (LeBlanc@mcc.ac.uk) fdisk 1.5 release, with
-           patched from Kevin Martin for DOS and OS/2 compatibility (1.5a);
-           Rik Faith (1.5b, 2.0).
-    frag: Werner Almesberger (1.0), Steffen Zahn (1.1), Rob Hooft (1.2), 
-          Steffen Zahn (szahn%masterix@emndev.siemens.co.at) (1.3), Michael
-          Bischoff <mbi@mo.math.nat.tu-bs.de> (1.4).
-    fsck.minix, mkfs.minix: Linus Torvalds, with modifications by: Rik
-                            Faith (faith@cs.unc.edu), Scott Heavner
-                            (sdh@po.cwru.edu), Dr. Wettstein
-                            (greg%wind.uucp@plains.nodak.edu), Daniel
-                            Quinlan (quinlan@yggdrasil.com).
-    mkswap: Linus Torvalds, with modifications by Mike Jagdis
-            (jaggy@purplet.demon.co.uk. )
-    setfdprm: Werner Almesberger (almesber@nessie.cs.id.ethz.ch)
-    llseek.c: from Remy Card's e2fsprogs-0.5b-WIP.tar.gz
-
-games:
-    banner: (8.3 (Berkeley) 4/2/94)
-    ddate: Druel the Chaotic aka Jeremy Johnson aka mpython@gnu.ai.mit.edu,
-           with modifications by Lee Harvey Oswald Smith, K.S.C.
-
-login-utils:
-    agetty: W. Z. Venema, ported by Peter Orbaek <poe@daimi.aau.dk>.
-            ftp.daimi.aau.dk:/pub/linux/poe/poeigl-1.32.tar.gz
-    chfn: Salvatore Valente <svalente@athena.mit.edu>
-    chsh: Salvatore Valente <svalente@athena.mit.edu>
-    last: 5.11 w/year (Berkeley) 6/29/88; Port by Michael Haardt with
-          changes by Peter Orbaek.
-          ftp://ftp.daimi.aau.dk/pub/linux/poe/admutil-1.14.tar.gz
-    login: 5.40 (Berkeley) 5/9/89; with ports by Michael Glad and Peter Orbaek
-           ftp.daimi.aau.dk:/pub/linux/poe/poeigl-1.32.tar.gz
-    mesg: Miquel van Smoorenburg (miquels@htsa.aha.nl,
-          miquels@drinkel.nl.mugnet.org).  From his sysvinit.tar.Z package.
-    newgrp: Michael Haardt, with modifications by Peter Orbaek.
-            ftp://ftp.daimi.aau.dk/pub/linux/poe/admutil-1.14.tar.gz
-    passwd: Peter Orbaek, with yp modifications by Alvaro Martinez
-            Echevarria (alvaro@enano.etsit.upm.es)
-            ftp://ftp.daimi.aau.dk/pub/linux/poe/admutil-1.14.tar.gz
-    shutdown: Peter Orbaek, with new modifications by Stephen Tweedie, Rik
-              Faith, and Dave (gentzel@nova.enet.dec.com).
-              ftp://ftp.daimi.aau.dk/pub/linux/poe/admutil-1.14.tar.gz
-    simpleinit: Peter Orbaek
-                ftp.daimi.aau.dk:/pub/linux/poe/poeigl-1.32.tar.gz
-    vipw: 5.16 (Berkeley) 3/3/91, with modifications by Mike Grupenhoff
-          <kashmir@umiacs.UMD.EDU> 
-    wall: 5.14 (Berkeley) 3/2/91 [From the BSD NET-2 (4.3bsd-reno)
-          distribution at wuarchive.wustl.edu:/mirrors/4.3-reno]
-
-makedev-1.4:
-    MAKEDEV-C: David A. Holland (dholland@husc.harvard.edu)
-               This version MODIFIED by Rik Faith (faith@cs.unc.edu)
-               sunsite.unc.edu:/pub/Linux/system/Admin/MAKEDEV-C-1.4.tar.gz
-
-
-misc-utils:
-    cal: 8.4 (Berkeley) 4/2/94, with modifications by Rik Faith and
-         Hein@student.tu-clausthal.de (Jochen Hein).
-         ftp.cdrom.com:/pub/bsd-sources/4.4BSD-Lite/usr/src/usr.bin
-    clear: Rik Faith
-    domainname: Peter Orbaek
-            ftp.daimi.aau.dk:/pub/linux/poe/poeigl-1.32.tar.gz
-    dsplit: David Arnstein (arnstein@netcom.com)
-            gatekeeper.dec.com:/pub/usenet/comp.sources.misc/volume40/dsplit
-    getopt (getoptprog): jhunix.hcf.jhu.edu:
-           /pub/public_domain_software/NetBSD/usr/src/usr.bin/getopt
-    hostid: Mitch DSouza (m.dsouza@mrc-apu.cam.ac.uk)
-            ftp.daimi.aau.dk:/pub/linux/poe/poeigl-1.32.tar.gz
-    hostname/dnsdomainname: Peter Tobias <tobias@server.et-inf.fho-emden.de>
-              This version (1.6) should also be available soon in:
-              nic.funet.fi:/pub/OS/Linux/PEOPLE/Linus/net-source/base/NetKit-A*
-    kill: BSD version, modified by Salvatore Valente <svalente@mit.edu>
-    logger: 8.1 (Berkeley) 6/6/93, with modifications by Rik Faith
-            ftp.cdrom.com:/pub/bsd-sources/4.4BSD-Lite/usr/src/usr.bin
-    look.c: 8.1 (Berkeley) 6/14/93, with modifications by Rik Faith
-            ftp.cdrom.com:/pub/bsd-sources/4.4BSD-Lite/usr/src/usr.bin
-    mcookie: Rik Faith (faith@cs.unc.edu)
-    md5sum: Branki Lankester and Colin Plumb.  The MD5 message-digest
-            algorithm is in the Public Domain.  This implementation
-            calculates message-digest information only, and can NOT be used
-            for encryption.  Therefore it is exportable from the USA.
-            Original sources in the MIT version of PGP 2.6.2.
-    namei: Roger S. Southwick, with modifications by Steve Tell.
-    reset: Rik Faith
-    script: 5.13 (Berkeley) 3/5/91, with modifications by Rick Sladkey
-            (jrs@world.std.com), Harald Koenig
-            (koenig@nova.tat.physik.uni-tuebingen.de).
-    setterm: Gordon Irlam (gordoni@cs.ua.oz.au), with modifications by
-             Peter MacDonald, Mika Liljeberg (liljeber@cs.Helsinki.FI),
-             John Walder (j-walder@uiuc.edu) [for dosemu].
-    tsort: 5.3 (Berkeley) 6/1/90
-           wuarchive.wustl.edu:/mirrors/4.3-reno
-    whereis: 5.5 (Berkeley) 4/18/91
-             wuarchive.wustl.edu:/mirrors/4.3-reno
-    write: 4.22 (Berkeley) 6/1/90, with modifications by Mike Grupenhoff
-           (kashmir@umiacs.umd.edu) .
-           wuarchive.wustl.edu:/mirrors/4.3-reno
-
-mount:
-    mount, umount, swapon
-
-    Rick Sladkey put together the mount-0.99.6.tar.Z package, and Stephen
-    Tweedie provided updates.  The utilities were originally from that
-    package (all appear to be by Doug Quale (quale@saavik.cs.wisc.edu),
-    with modifications by H. J. Lu (hlu@eecs.wsu.edu) on 11/25/92; Rick
-    Sladkey (jrs@world.std.com) in January 1993; and Stephen Tweedie
-    <sct@dcs.ed.ac.uk> on 8 October 1993.  This distribution mount now
-    supports NFS stuff.  I have modified the man pages.  I have also added
-    a small patch from Hamish Glen Coleman (t933093@minyos.xx.rmit.OZ.AU)
-    which restores the -o semantics.
-    
-    Updated with Rick Sladkey's mount-0.99.14.tar.gz package, and with
-    extra patches from Rick.  Adam J. Richter allowed -t option to be
-    optional. Patrick J. Volkerding (volkerdi@mhd1.moorhead.msus.edu) and
-    Mitchum DSouza both provided patches that fixed the (null) problem when
-    not using -t. Mitchum DSouza
-    (mitch@mrc-applied-psychology.cambridge.ac.uk) added support for loop
-    device mounts. Sebastian Lederer
-    (lederer@next-pc.informatik.uni-bonn.de) added support for sending an
-    unmount RPC call to the server when an NFS-filesystem is unmounted.
-    Sander van Malssen (svm@kozmix.hacktic.nl) added support for remounting
-    readonly file systems readonly.  Mike Grupenhoff
-    <kashmir@umiacs.UMD.EDU> added a probe of the superblock for the type
-    before /proc/filesystems is checked.  Andries.Brouwer@cwi.nl fixed up
-    error reporting.
-
-selection:
-    The complete selection-1.5 package, by Andrew Haylett
-    <ajh@gec-mrc.co.uk>, 17th June 1993, is included.  Kernel patches are
-    no longer necessary for modern kernels, but these were tiny so I left
-    them in for historical reasons.  The Makefile was modified for this
-    distribution.  With changes from Rick Sladkey.
-
-sys-utils:
-    MAKEDEV: Nick Holloway <Nick.Holloway@alfie.demon.co.uk>
-    arch: Rik Faith <faith@cs.unc.edu>
-    chroot: Rick Sladkey <jrs@world.std.com>
-    clock: Originally from the timesrc-1.2.tar.Z package, Charles Hedrick,
-           hedrick@cs.rutgers.edu (V1.0); Rob Hooft, hooft@chem.ruu.nl
-           (V1.1); Harald Koenig (koenig@nova.tat.physik.uni-tuebingen.de)
-           (V1.2).  With additional changes: Hamish Coleman
-           (hamish@zot.apana.org.au) (V1.2a); Alan Modra
-           (alan@spri.levels.unisa.edu.au (V1.3, V1.4).
-    ctrlaltdel: Peter Orbaek <poe@daimi.aau.dk>
-                ftp://ftp.daimi.aau.dk/pub/linux/poe/admutil-1.14.tar.gz
-    dmesg: Theodore Ts'o (tytso@athena.mit.edu); Rick Sladkey
-           (jrs@world.std.com)
-    ipcrm: From the ipcdelta.tar.z distribution by krishna
-           balasub@cis.ohio-state.edu on 3/15/93.  ipc.info and ipc.texi
-           are also from that distribution.
-    ipcs: Also from the ipcdelta.tar.z distribution by krishna
-          balasub@cis.ohio-state.edu, with patches from Mike Jagdis
-          (jaggy@purplet.demon.co.uk)
-    kbdrate: Rik Faith (faith@cs.unc.edu), with patches from
-             Andries.Brouwer@cwi.nl and John Bowman
-             (bowman@hagar.ph.utexas.edu)
-    lpcntl: Nigel Gamble (nigel@gate.net)
-    rdev: almesber@nessie.cs.id.ethz.ch (Werner Almesberger), with
-          modifications from Peter MacDonald, Stephen Tweedie
-          (sct@dcs.ed.ac.uk), and Dave (gentzel@nova.enet.dec.com)
-    readprofile: Alessandro Rubini
-    renice: 8.1 (Berkeley) 6/9/93
-            ftp.cdrom.com:/pub/bsd-sources/4.4BSD-Lite/usr/src/usr.bin
-    setserial: Michael K. Johnson (johnsonm@stolaf.edu) re-released Rick
-               Sladkey's setserial in January 1993, with changes by
-               Theodore Ts'o (tytso@mit.edu).  I think that Theodore also
-               did extensive changes for version 2.01, I can't find any
-               notes about this in the documentation. However, Theodore
-               Ts'o (tytso@ATHENA.MIT.EDU) released version 2.10, and that
-               is now included.
-    setsid: Rick Sladkey <jrs@world.std.com>
-    sln: Mike Parker and David MacKenzie (from Linux's libc)
-    sync: Nick Holloway, with thanks to James Bonfield
-    tunelp: Michael K. Johnson (johnsonm@nigel.vnet.net)
-    update_state: Rik Faith (faith@cs.unc.edu)
-
-syslogd:
-   5.45 (Berkeley) 3/2/91
-
-   Most of the changes for syslogd come from Rick Sladkey
-   (jrs@world.std.com), but I'd like to thank other people who sent in
-   changes (which usually got forwarded to Rick): Carsten Paeth
-   (calle@calle.in-berlin.de) and Kaz Sasayama (kaz@lilia.iijnet.or.jp).
-
-text-utils:
-    col: 5.3 (Berkeley) 2/2/91; with patches from Andries.Brouwer@cwi.nl
-         and Carl Christofferson (cchris@connected.com)
-         wuarchive.wustl.edu:/mirrors/4.3-reno/{bin,usr.bin}
-    colcrt: 8.1 (Berkeley) 6/6/93 (Bill Joy)
-            ftp.cdrom.com:/pub/bsd-sources/4.4BSD-Lite/usr/src/usr.bin
-    colrm: 5.4 (Berkeley) 6/1/90 (Jeff Schriebman)
-    column: 8.3 (Berkeley) 4/2/94
-            ftp.cdrom.com:/pub/bsd-sources/4.4BSD-Lite/usr/src/usr.bin
-    hexdump: 5.5 (Berkeley) 6/1/90
-             wuarchive.wustl.edu:/mirrors/4.3-reno/{bin,usr.bin}
-    more: 5.19 (Berkeley) 6/29/88 (Eric Shienbrood, Geoff Peck, John Foderaro)
-    rev: 5.2 (Berkeley) 3/21/92; with modifications by Charles Hannum
-         (mycroft@gnu.ai.mit.edu), Brian Koehmstedt (bpk@gnu.ai.mit.edu),
-         bjdouma@xs4all.nl
-         wuarchive.wustl.edu:/mirrors/4.3-reno/{bin,usr.bin}
-    strings: 5.10 (Berkeley) 5/23/91; with patches from Vitor Duarte
-             <vad@fct.unl.pt>
-             wuarchive.wustl.edu:/mirrors/4.3-reno/{bin,usr.bin}
-    ul: 8.1 (Berkeley) 6/6/93
-        ftp.cdrom.com:/pub/bsd-sources/4.4BSD-Lite/usr/src/usr.bin
-
-time:
-    elsie.nci.nih.gov:/pub/classictzcode.tar.gz
-    elsie.nci.nih.gov:/pub/classictzdata.tar.gz
-    (The zoneinfo database was updated Dec 1994.)
-
-%%
-* bin/arch
-* bin/dmesg
-* bin/dnsdomainname
-* bin/domainname
-* bin/hostname
-* bin/kill
-* bin/login
-* bin/more
-* bin/mount
-* bin/setserial
-* bin/sync
-* bin/umount
-* dev/MAKEDEV
-* dev/MAKEDEV-C
-* etc/DEVINFO
-* etc/MAKEDEV.cfg
-* etc/fdprm
-* sbin/agetty
-* sbin/cfdisk
-* sbin/clock
-* sbin/fastboot
-* sbin/fasthalt
-* sbin/fdisk
-* sbin/fsck.minix
-* sbin/halt
-* sbin/kbdrate
-* sbin/mkfs.minix
-* sbin/mkswap
-* sbin/reboot
-* sbin/shutdown
-* sbin/simpleinit
-* sbin/sln
-* sbin/swapoff
-* sbin/swapon
-* usr/bin/cal
-* usr/bin/chfn
-* usr/bin/chsh
-* usr/bin/clear
-* usr/bin/col
-* usr/bin/colcrt
-* usr/bin/colrm
-* usr/bin/column
-* usr/bin/dsplit
-* usr/bin/fdformat
-* usr/bin/getopt
-* usr/bin/hexdump
-* usr/bin/hostid
-* usr/bin/ipcrm
-* usr/bin/ipcs
-* usr/bin/last
-* usr/bin/logger
-* usr/bin/look
-* usr/bin/lpcntl
-* usr/bin/mcookie
-* usr/bin/md5sum
-* usr/bin/mesg
-* usr/bin/namei
-* usr/bin/newgrp
-* usr/bin/passwd
-* usr/bin/ramsize
-* usr/bin/rdev
-* usr/bin/readprofile
-* usr/bin/renice
-* usr/bin/reset
-* usr/bin/rev
-* usr/bin/rootflags
-* usr/bin/script
-* usr/bin/selection
-* usr/bin/setfdprm
-* usr/bin/setsid
-* usr/bin/setterm
-* usr/bin/strings
-* usr/bin/swapdev
-* usr/bin/tsort
-* usr/bin/tunelp
-* usr/bin/ul
-* usr/bin/vidmode
-* usr/bin/wall
-* usr/bin/whereis
-* usr/bin/write
-* usr/info/ipc.info
-* usr/lib/libz.a
-* usr/lib/more.help
-* usr/lib/zoneinfo
-* usr/man/man1/arch.1
-* usr/man/man1/cal.1
-* usr/man/man1/chfn.1
-* usr/man/man1/chsh.1
-* usr/man/man1/clear.1
-* usr/man/man1/col.1
-* usr/man/man1/colcrt.1
-* usr/man/man1/colrm.1
-* usr/man/man1/column.1
-* usr/man/man1/dnsdomainname.1
-* usr/man/man1/domainname.1
-* usr/man/man1/dsplit.1
-* usr/man/man1/getopt.1
-* usr/man/man1/hexdump.1
-* usr/man/man1/hostid.1
-* usr/man/man1/hostname.1
-* usr/man/man1/kill.1
-* usr/man/man1/last.1
-* usr/man/man1/logger.1
-* usr/man/man1/login.1
-* usr/man/man1/look.1
-* usr/man/man1/md5sum.1
-* usr/man/man1/mesg.1
-* usr/man/man1/more.1
-* usr/man/man1/namei.1
-* usr/man/man1/newgrp.1
-* usr/man/man1/passwd.1
-* usr/man/man1/readprofile.1
-* usr/man/man1/reset.1
-* usr/man/man1/rev.1
-* usr/man/man1/script.1
-* usr/man/man1/selection.1
-* usr/man/man1/setterm.1
-* usr/man/man1/strings.1
-* usr/man/man1/tsort.1
-* usr/man/man1/ul.1
-* usr/man/man1/wall.1
-* usr/man/man1/whereis.1
-* usr/man/man1/write.1
-* usr/man/man3/newctime.3
-* usr/man/man3/newtzset.3
-* usr/man/man5/DEVINFO.5
-* usr/man/man5/MAKEDEV.cfg.5
-* usr/man/man5/fstab.5
-* usr/man/man5/nfs.5
-* usr/man/man5/syslog.conf.5
-* usr/man/man5/tzfile.5
-* usr/man/man6/banner.6
-* usr/man/man6/ddate.6
-* usr/man/man8/MAKEDEV-C.8
-* usr/man/man8/MAKEDEV.8
-* usr/man/man8/agetty.8
-* usr/man/man8/cfdisk.8
-* usr/man/man8/chroot.8
-* usr/man/man8/clock.8
-* usr/man/man8/ctrlaltdel.8
-* usr/man/man8/dmesg.8
-* usr/man/man8/fastboot.8
-* usr/man/man8/fasthalt.8
-* usr/man/man8/fdformat.8
-* usr/man/man8/fdisk.8
-* usr/man/man8/frag.8
-* usr/man/man8/fsck.minix.8
-* usr/man/man8/halt.8
-* usr/man/man8/ipcrm.8
-* usr/man/man8/ipcs.8
-* usr/man/man8/kbdrate.8
-* usr/man/man8/lpcntl.8
-* usr/man/man8/mkfs.minix.8
-* usr/man/man8/mkswap.8
-* usr/man/man8/mount.8
-* usr/man/man8/ramsize.8
-* usr/man/man8/rdev.8
-* usr/man/man8/reboot.8
-* usr/man/man8/renice.8
-* usr/man/man8/rootflags.8
-* usr/man/man8/setfdprm.8
-* usr/man/man8/setserial.8
-* usr/man/man8/setsid.8
-* usr/man/man8/shutdown.8
-* usr/man/man8/simpleinit.8
-* usr/man/man8/swapdev.8
-* usr/man/man8/swapoff.8
-* usr/man/man8/swapon.8
-* usr/man/man8/sync.8
-* usr/man/man8/syslogd.8
-* usr/man/man8/tunelp.8
-* usr/man/man8/umount.8
-* usr/man/man8/update_state.8
-* usr/man/man8/vidmode.8
-* usr/man/man8/vipw.8
-* usr/man/man8/zdump.8
-* usr/man/man8/zic.8
-* usr/sbin/chroot
-* usr/sbin/ctrlaltdel
-* usr/sbin/frag
-* usr/sbin/syslogd
-* usr/sbin/update_state
-* usr/sbin/vipw
-* usr/sbin/zdump
-* usr/sbin/zic
diff --git a/util-linux-2.1.lsm b/util-linux-2.1.lsm
deleted file mode 100644 (file)
index a3c8d51..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-Begin3
-Title:          util-linux: Miscellaneous utilities for Linux
-Version:        2.1
-Entered-date:   Thu Feb 16 09:23:18 1995
-Description:    reboot shutdown simpleinit sln swapoff swapon cal chfn chsh
-                clear col colcrt colrm column dnsdomainname domainname
-                dsplit fdformat getopt hexdump hostid hostname ipcrm ipcs
-                last logger look lpcntl mcookie md5sum mesg namei newgrp
-                passwd ramsize rdev readprofile renice reset rev rootflags
-                script selection setfdprm setsid setterm strings swapdev
-                tsort tunelp ul vidmode wall whereis write chroot
-                ctrlaltdel frag syslogd update_state vipw zdump zic
-Keywords:       essential utilities
-Author:         several
-Maintained-by:  faith@cs.unc.edu (Rik Faith)
-Primary-site:   ftp.cs.unc.edu /pub/users/faith/linux
-                640k util-linux-2.1.tar.gz
-                570k util-linux-2.1.bin.tar.gz
-Alternate-site: tsx-11.mit.edu /pub/linux/packages/utils
-Alternate-site: sunsite.unc.edu /pub/Linux/system/Misc
-Platforms:      Linux 1.1.8x, GNU tar
-Copying-policy: GPL, BSD, others
-End
index 030f849795a5ad3ec1e656c60ebfcdd06db37ab5..4b8deb079092d4c3b51719a04a31335366ccbd37 100644 (file)
--- a/version.h
+++ b/version.h
@@ -1,2 +1,3 @@
-#define UTIL_LINUX 1
-char *util_linux_version="util-linux 2.8";
+#define UTIL_LINUX_VERSION     "2.9i"
+
+const char * const util_linux_version = "util-linux " UTIL_LINUX_VERSION;