summaryrefslogtreecommitdiffstats
path: root/hwclock
diff options
context:
space:
mode:
authorKarel Zak2006-12-07 00:25:58 +0100
committerKarel Zak2006-12-07 00:25:58 +0100
commit63cccae4684f83d2a462bc8abf24e51d1bd6efb6 (patch)
tree433db3f0b44e0f46e4130141f4a59db9c3564557 /hwclock
parentImported from util-linux-2.11r tarball. (diff)
downloadkernel-qcow2-util-linux-63cccae4684f83d2a462bc8abf24e51d1bd6efb6.tar.gz
kernel-qcow2-util-linux-63cccae4684f83d2a462bc8abf24e51d1bd6efb6.tar.xz
kernel-qcow2-util-linux-63cccae4684f83d2a462bc8abf24e51d1bd6efb6.zip
Imported from util-linux-2.11t tarball.
Diffstat (limited to 'hwclock')
-rw-r--r--hwclock/Makefile4
-rw-r--r--hwclock/README.aeb9
-rw-r--r--hwclock/README.shhopt-1.1155
-rw-r--r--hwclock/adjtime.patch302
-rw-r--r--hwclock/cmos.c34
-rw-r--r--hwclock/hwclock.83
-rw-r--r--hwclock/hwclock.c718
-rw-r--r--hwclock/kd.c3
-rw-r--r--hwclock/rtc.c38
-rw-r--r--hwclock/shhopt-1.1.lsm17
-rw-r--r--hwclock/shhopt.c468
-rw-r--r--hwclock/shhopt.h33
12 files changed, 474 insertions, 1310 deletions
diff --git a/hwclock/Makefile b/hwclock/Makefile
index 70ff6436c..88aa50cd8 100644
--- a/hwclock/Makefile
+++ b/hwclock/Makefile
@@ -16,9 +16,9 @@ SBIN= hwclock
all: $(SBIN)
-hwclock.o: hwclock.c shhopt.h
+hwclock.o: hwclock.c
hwclock.o cmos.o rtc.o kd.o: clock.h
-hwclock: hwclock.o shhopt.o cmos.o rtc.o kd.o
+hwclock: hwclock.o cmos.o rtc.o kd.o
CWFLAGS := $(subst -Wmissing-prototypes,,$(CFLAGS))
diff --git a/hwclock/README.aeb b/hwclock/README.aeb
deleted file mode 100644
index 3955f9050..000000000
--- a/hwclock/README.aeb
+++ /dev/null
@@ -1,9 +0,0 @@
-This directory contains the hwclock stuff as fixed by me.
-It should work on all architectures.
-
-Bryan has backported my changes to his original source,
-so the present directory should be superfluous -
-however, his code fails on my Sparc.
-Will look at it later.
-
-Andries Brouwer - aeb@cwi.nl
diff --git a/hwclock/README.shhopt-1.1 b/hwclock/README.shhopt-1.1
deleted file mode 100644
index 766d6cbdc..000000000
--- a/hwclock/README.shhopt-1.1
+++ /dev/null
@@ -1,155 +0,0 @@
-shhopt - library for parsing command line options.
-==================================================
-
-This is a set of functions for parsing command line options. Both
-traditional one-character options, and GNU-style --long-options are
-supported.
-
-
-What separates this from traditional getopt?
---------------------------------------------
-
-This library does more of the parsing for you. You set up a special
-structure describing the names and types of the options you want your
-program to support. In the structure you also give addresses of
-variables to update or functions to call for the various
-options. By calling optParseOptions, all options in argv are parsed
-and removed from argv. What is left, are the non-optional arguments to
-your program.
-
-The down-side of this, is that you won't be able to make a program
-where the position of the options between the non-options are
-significant.
-
-
-Usage
------
-
-To see how to use this library, take a look at the sample program
-example.c.
-
-A brief explanation:
-
-To parse your command line, you need to create and initialize an array
-of optStruct's. Each element in the array describes a long and short
-version of an option and specifies what type of option it is and how
-to handle it.
-
-The structure fields (see also shhopt.h):
-
- `shortName' is the short option name without the leading '-'.
-
- `longName' is the long option name without the leading "--".
-
- `type' specifies what type of option this is. (Does it expect an
- argument? Is it a flag? If it takes an argument,what type should
- it be?)
-
- `arg' is either a function to be called with the argument from
- the commandline, or a pointer to a location in which to store
- the value.
-
- `flags' indicates whether `arg' points to a function or a storage
- location.
-
-The different argument types:
-
- `OPT_END' flags this as the last element in the options array.
-
- `OPT_FLAG' indicates an option that takes no arguments. If `arg' is
- not a function pointer, the value of `arg' will be set to 1 if
- this flag is found on the command line.
-
- `OPT_STRING' expects a string argument.
-
- `OPT_INT' expects an int argument.
-
- `OPT_UINT' expects an unsigned int argument.
-
- `OPT_LONG' expects a long argument.
-
- `OPT_ULONG' expects an unsigned long argument.
-
-The different flag types:
-
- `OPT_CALLFUNC' indicates that `arg' is a function pointer. If this
- is not given, `arg' is taken as a pointer to a variable.
-
-
-Notes
------
-
-* A dash (`-') by itself is not taken as any kind of an option, as
- several programs use this to indicate the special files stdin and
- stdout. It is thus left as a normal argument to the program.
-
-* Two dashes (`--') as an argument, is taken to mean that the rest of
- the arguments should not be scanned for options. This simplifies
- giving names of files that start with a dash.
-
-* Short (one-character) options accept parameters in two ways, either
- directly following the option in the same argv-entry, or in the next
- argv-entry:
-
- -sPARAMETER
- -s PARAMETER
-
-* Long options accept parameters in two ways:
-
- --long-option=PARAMETER
- --long-option PARAMETER
-
- To follow the GNU-tradition, your program documentation should use
- the first form.
-
-* Several one-character options may be combined after a single
- dash. If any of the options requires a parameter, the rest of the
- string is taken as this parameter. If there is no "rest of the
- string", the next argument is taken as the parameter.
-
-* There is no support for floating point (double) arguments to
- options. This is to avoid unnecessary linking with the math
- library. See example.c for how to get around this by writing a
- function converting a string argument to a double.
-
-
-Portability
------------
-
-If your libc lacks strtoul, you will need to link with GNU's -liberty,
-that may be found by anonymous ftp to prep.ai.mit.edu:/pub/gnu
-
-The library has (more or less recently) been compiled and `tested' on
-the following systems:
-
- IRIX Release 5.3 IP22
- Linux 1.2.9
- SunOS Release 4.1.3_U1 (-liberty needed)
- ULTRIX V4.4 (Rev. 69)
-
-All compilations were done using GNU's gcc, and GNU's make.
-
-
-Author
-------
-
-The program is written by
-
- Sverre H. Huseby
- Maridalsvn. 122, leil. 101
- N-0461 Oslo
- Norway
-
- sverrehu@ifi.uio.no
- http://www.ifi.uio.no/~sverrehu/
-
-You can use and copy this for free. If you decide to use it, please do
-me three small favours:
-
- 1. Tell me! (E-mail, postcard, letter, whatever. If you wish
- to give me something, please send a bottle of your
- favourite beer (making this BeerWare))
- 2. Let your friends and favourite download site have a copy!
- (with all files intact, please..)
- 3. Report any bugs you find!
-
diff --git a/hwclock/adjtime.patch b/hwclock/adjtime.patch
deleted file mode 100644
index 81d0430fd..000000000
--- a/hwclock/adjtime.patch
+++ /dev/null
@@ -1,302 +0,0 @@
-From ao112@rgfn.epcc.edu Fri Mar 19 06:27:26 1999
-Received: from rgfn.epcc.edu (rgfn.epcc.edu [208.136.234.19]) by hera.cwi.nl with ESMTP
- id GAA27711 for <Andries.Brouwer@cwi.nl>; Fri, 19 Mar 1999 06:27:23 +0100 (MET)
-Received: (from ao112@localhost)
- by rgfn.epcc.edu (8.8.8/8.8.8) id WAA16797;
- Thu, 18 Mar 1999 22:27:19 -0700 (MST)
-Date: Thu, 18 Mar 1999 22:27:19 -0700 (MST)
-Message-Id: <199903190527.WAA16797@rgfn.epcc.edu>
-From: ao112@rgfn.epcc.edu (James P. Rutledge)
-To: Andries.Brouwer@cwi.nl
-Subject: Re: hwclock patch for drift_factor calculation improvement
-Reply-To: ao112@rgfn.epcc.edu
-Status: R
-
-
-
->
->Could you perhaps make your patch relative to
->util-linux-2.9n (found in ftp.cwi.nl/pub/aeb/util-linux/util-linux-2.9n.tar.gz)
->?
->
->(The hwclock stuff has changed quite a bit since 2.9g.)
->
->Andries
->
-
-Andries;
-
-Per your request, the patch has been modified for util-linux version
-2.9n, from the version for 2.9g.
-
-The program "hwclock" (version 2.4c) could give more accurate
-values for the drift factor that it places in the file "/etc/adjtime".
-
-A patch to improve the accuracy is included.
-
-I have incorporated some error sources which were not compensated
-for into the drift factor calculation (performed when the "--set"
-or the "--systohc" option is used) to make it more accurate.
-In particular, the sync delay between the desired set time and the
-start of the hardware clock second, and the expected drift since the
-last hardware clock adjustment are now accounted for in the drift
-factor calculation.
-
-With this patch, if at any time an adjust operation is attempted and
-the hardware clock is found to be not valid, then the calibration
-and adjustment time is set to zero to insure that if the hardware
-clock should coincidentally return to validity, a calibration is not
-done with bad history data (hardware clock info bad) and an adjust is
-not attempted on bad (but now passing validity test) hardware clock
-data. (With this patch, a previous calibration time of zero causes
-the calibration time to initialize with the current time, when the
-hardware clock is set, but no change is made to the drift factor,
-so in effect, an initial calibration is started over while the previous
-drift factor is retained.)
-
-Also, the behavior in the case of an initially missing "/etc/adjtime"
-file or such a file produced by the predecessor "clock" program has
-been slightly improved as follows:
-
- With this patch, if the file exists but was produced by "clock"
- and, thus, is given a zero calibration time, the drift factor is
- not updated upon the first calibration by "hwclock", but is left alone
- and is only changed by subsequent calibrations.
-
- With this patch, if the file does not exist and, thus, is given
- a zero calibration time, the drift factor is set to zero upon the
- first calibration by "hwclock" and is then changed, as appropriate, by
- subsequent calibrations.
-
- Also, with this patch, an "--adjust" operation against a non-existent
- "/etc/adjtime" file or one which has zero as the last adjustment
- time will not change the hardware clock setting.
-
-A context diff for a patch to the file "hwclock.c" in the directory
-"util-linux-2.9n/clock" is appended.
-To use the patch, "cd" to the directory "util-linux-2.9n/clock".
-Run "patch < bug-report", where "bug-report" is the file name of
-this mail message, to get new file "hwclock.c" which contains the proposed
-new version. This patch is, of course, submitted per the GPL and the
-appropriate "NO WARRANTY OF ANY KIND" and "USE AT YOUR OWN RISK"
-disclaimers apply.
-
-Note that the patch presumptuously changes the "hwclock.c" version
-number from 2.4c to 2.4c1 in "hwclock.c".
-
-Jim
-
------------------- Patch file follows ----------------------------
-*** hwclock.c Thu Mar 18 22:04:01 1999
---- new-hwclock.c Thu Mar 18 22:03:18 1999
-***************
-*** 76,86 ****
-
- #include "clock.h"
- #include "../version.h"
-
- #define MYNAME "hwclock"
-! #define VERSION "2.4c"
-
- char *progname = MYNAME;
-
- /* The struct that holds our hardware access routines */
- struct clock_ops *ur;
---- 76,86 ----
-
- #include "clock.h"
- #include "../version.h"
-
- #define MYNAME "hwclock"
-! #define VERSION "2.4c1"
-
- char *progname = MYNAME;
-
- /* The struct that holds our hardware access routines */
- struct clock_ops *ur;
-***************
-*** 581,601 ****
-
-
- static void
- adjust_drift_factor(struct adjtime *adjtime_p,
- const time_t nowtime,
-! 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
- to <hclocktime>.
-
-- We assume that the user has been doing regular drift adjustments
-- using the drift factor in the adjtime file, so if <nowtime> and
-- <clocktime> are different, that means the adjustment factor isn't
-- quite right.
--
- 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
---- 581,598 ----
-
-
- static void
- adjust_drift_factor(struct adjtime *adjtime_p,
- const time_t nowtime,
-! const bool hclock_valid,
-! const time_t hclocktime,
-! const float sync_delay ) {
- /*---------------------------------------------------------------------------
- Update the drift factor in <*adjtime_p> to reflect the fact that the
- Hardware Clock was calibrated to <nowtime> and before that was set
- to <hclocktime>.
-
- 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
-***************
-*** 604,629 ****
- ----------------------------------------------------------------------------*/
- 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))
-! * 24 * 60 * 60;
-
- if (debug)
-! printf("Clock drifted %d seconds in the past %d seconds "
- "in spite of a drift factor of %f seconds/day.\n"
- "Adjusting drift factor by %f seconds/day\n",
-! (int) (nowtime - hclocktime),
-! (int) (hclocktime - adjtime_p->last_calib_time),
- adjtime_p->drift_factor,
- factor_adjust );
-
- adjtime_p->drift_factor += factor_adjust;
- }
---- 601,642 ----
- ----------------------------------------------------------------------------*/
- if (!hclock_valid) {
- if (debug)
- printf("Not adjusting drift factor because the Hardware Clock "
- "previously contained garbage.\n");
-+ } else if (adjtime_p->last_calib_time == 0) {
-+ if (debug)
-+ printf("Not adjusting drift factor because last calibration "
-+ "time is zero,\nso history is bad and calibration startover "
-+ "is necessary.\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 sec_per_day = 24.0 * 60.0 * 60.0;
-! float atime_per_htime; /* adjusted time units per hardware time unit */
-! float adj_days; /* days since last adjustment (in hardware clock time) */
-! float cal_days; /* days since last calibration (in hardware clock time) */
-! float exp_drift; /* expected drift (sec) since last adjustment */
-! float unc_drift; /* uncorrected drift (sec) since last calibration */
-! float factor_adjust; /* amount to add to previous drift factor */
-! atime_per_htime = 1.0 + adjtime_p->drift_factor / sec_per_day;
-! adj_days = (float)(hclocktime - adjtime_p->last_adj_time) / sec_per_day;
-! exp_drift = adj_days * adjtime_p->drift_factor + adjtime_p->not_adjusted;
-! unc_drift = (float)(nowtime - hclocktime) + sync_delay - exp_drift;
-! cal_days = ((float)(adjtime_p->last_adj_time - adjtime_p->last_calib_time)
-! + adjtime_p->not_adjusted) / (sec_per_day * atime_per_htime)
-! + adj_days;
-! factor_adjust = unc_drift / cal_days;
-
- if (debug)
-! printf("Clock drifted %.1f seconds in the past %d seconds "
- "in spite of a drift factor of %f seconds/day.\n"
- "Adjusting drift factor by %f seconds/day\n",
-! unc_drift,
-! (int) (nowtime - adjtime_p->last_calib_time),
- adjtime_p->drift_factor,
- factor_adjust );
-
- adjtime_p->drift_factor += factor_adjust;
- }
-***************
-*** 764,773 ****
---- 777,794 ----
-
- ----------------------------------------------------------------------------*/
- if (!hclock_valid) {
- fprintf(stderr, "The Hardware Clock does not contain a valid time, "
- "so we cannot adjust it.\n");
-+ adjtime_p->last_calib_time = 0; /* calibration startover is required */
-+ adjtime_p->last_adj_time = 0;
-+ adjtime_p->not_adjusted = 0;
-+ adjtime_p->dirty = TRUE;
-+ } else if (adjtime_p->last_adj_time == 0) {
-+ if (debug)
-+ printf("Not setting clock because last adjustment time is zero, "
-+ "so history is bad.");
- } else {
- int adjustment;
- /* Number of seconds we must insert in the Hardware Clock */
- float retro;
- /* Fraction of second we have to remove from clock after inserting
-***************
-*** 878,888 ****
- time_diff(read_time, startup_time));
- *retcode_p = 0;
- } else if (set) {
- set_hardware_clock_exact(set_time, startup_time,
- universal, testing);
-! adjust_drift_factor(&adjtime, set_time, hclock_valid, hclocktime);
- *retcode_p = 0;
- } else if (adjust) {
- do_adjustment(&adjtime, hclock_valid, hclocktime,
- read_time, universal, testing);
- *retcode_p = 0;
---- 899,910 ----
- time_diff(read_time, startup_time));
- *retcode_p = 0;
- } else if (set) {
- set_hardware_clock_exact(set_time, startup_time,
- universal, testing);
-! adjust_drift_factor(&adjtime, set_time, hclock_valid, hclocktime,
-! time_diff(read_time, startup_time));
- *retcode_p = 0;
- } else if (adjust) {
- do_adjustment(&adjtime, hclock_valid, hclocktime,
- read_time, universal, testing);
- *retcode_p = 0;
-***************
-*** 898,908 ****
-
- set_hardware_clock_exact((time_t) reftime.tv_sec, reftime,
- universal, testing);
- *retcode_p = 0;
- adjust_drift_factor(&adjtime, (time_t) reftime.tv_sec, hclock_valid,
-! hclocktime);
- } else if (hctosys) {
- rc = set_system_clock(hclock_valid, hclocktime, testing);
- if (rc != 0) {
- printf("Unable to set system clock.\n");
- *retcode_p = 1;
---- 920,930 ----
-
- set_hardware_clock_exact((time_t) reftime.tv_sec, reftime,
- universal, testing);
- *retcode_p = 0;
- adjust_drift_factor(&adjtime, (time_t) reftime.tv_sec, hclock_valid,
-! hclocktime, (float)(read_time.tv_usec / 1E6));
- } else if (hctosys) {
- rc = set_system_clock(hclock_valid, hclocktime, testing);
- if (rc != 0) {
- printf("Unable to set system clock.\n");
- *retcode_p = 1;
-
diff --git a/hwclock/cmos.c b/hwclock/cmos.c
index aed122cb1..a5eec0372 100644
--- a/hwclock/cmos.c
+++ b/hwclock/cmos.c
@@ -65,15 +65,18 @@ int inb(int c){ return 0; }
#define BCD_TO_BIN(val) ((val)=((val)&15) + ((val)>>4)*10)
#define BIN_TO_BCD(val) ((val)=(((val)/10)<<4) + (val)%10)
-/* The epoch.
- Unix uses 1900 as epoch for a struct tm, and 1970 for a time_t.
- But what was written to CMOS?
- Digital DECstations use 1928 - this is on a mips
- Digital Unix uses 1952.
- Windows NT uses 1980.
- The ARC console expects to boot Windows NT and uses 1980.
- (But a Ruffian uses 1900, just like SRM.)
- It is reported that ALPHA_PRE_V1_2_SRM_CONSOLE uses 1958. */
+/*
+ * The epoch.
+ *
+ * Unix uses 1900 as epoch for a struct tm, and 1970 for a time_t.
+ * But what was written to CMOS?
+ * Digital DECstations use 1928 - this is on a mips or alpha
+ * Digital Unix uses 1952, e.g. on AXPpxi33
+ * Windows NT uses 1980.
+ * The ARC console expects to boot Windows NT and uses 1980.
+ * (But a Ruffian uses 1900, just like SRM.)
+ * It is reported that ALPHA_PRE_V1_2_SRM_CONSOLE uses 1958.
+ */
#define TM_EPOCH 1900
int cmos_epoch = 1900;
@@ -154,12 +157,13 @@ set_cmos_epoch(int ARCconsole, int SRM) {
return;
}
- /* The kernel source today says: read the year. If it is
- in 11-43 then the epoch is 1980 (this covers 1991-2023).
- Otherwise, if it is less than 96 then the epoch is 1952
- (this covers 1952-1962 and 1996-2047). Otherwise, the epoch
- is 1900 (this covers 1996-1999, or rather 1996-2155). */
-
+ /* The kernel source today says: read the year.
+ If it is in 0-19 then the epoch is 2000.
+ If it is in 20-47 then the epoch is 1980.
+ If it is in 48-69 then the epoch is 1952.
+ If it is in 70-99 then the epoch is 1928.
+ Otherwise the epoch is 1900.
+ Clearly, this must be changed before 2019. */
/* See whether we are dealing with SRM or MILO, as they have
different "epoch" ideas. */
diff --git a/hwclock/hwclock.8 b/hwclock/hwclock.8
index d62f5035e..0d5f014c9 100644
--- a/hwclock/hwclock.8
+++ b/hwclock/hwclock.8
@@ -590,10 +590,9 @@ on old systems)
.BR tzset (3)
.SH AUTHORS
-Written By Bryan Henderson, September 1996 (bryanh@giraffe-data.com),
+Written by Bryan Henderson, September 1996 (bryanh@giraffe-data.com),
based on work done on the
.I clock
program by Charles Hedrick, Rob Hooft, and Harald Koenig.
See the source code for complete history and credits.
-
diff --git a/hwclock/hwclock.c b/hwclock/hwclock.c
index 20c548eb0..9cf46dda1 100644
--- a/hwclock/hwclock.c
+++ b/hwclock/hwclock.c
@@ -20,6 +20,7 @@
*
* Fix for Award 2094 bug, Dave Coffin (dcoffin@shore.net) 11/12/98
* Change of local time handling, Stefan Ring <e9725446@stud3.tuwien.ac.at>
+ * Change of adjtime handling, James P. Rutledge <ao112@rgfn.epcc.edu>.
*
* Distributed under GPL
*/
@@ -78,13 +79,13 @@
#include <sys/time.h>
#include <sys/stat.h>
#include <stdarg.h>
+#include <getopt.h>
+#include <sysexits.h>
-#include "shhopt.h"
#include "clock.h"
#include "nls.h"
#define MYNAME "hwclock"
-#define VERSION "2.4c"
char *progname = MYNAME;
@@ -108,14 +109,17 @@ struct adjtime {
updated since read from the disk file).
*/
bool dirty;
+
/* line 1 */
- float drift_factor;
+ double drift_factor;
time_t last_adj_time;
- float not_adjusted;
+ double not_adjusted;
+
/* line 2 */
time_t last_calib_time;
/* The most recent time that we set the clock from an external
authority (as opposed to just doing a drift adjustment) */
+
/* line 3 */
enum a_local_utc {LOCAL, UTC, UNKNOWN} local_utc;
/* To which time zone, local or UTC, we most recently set the
@@ -170,18 +174,18 @@ read_date_from_file (struct tm *tm) {
write_date_to_file (tm);
}
-static float
+static double
time_diff(struct timeval subtrahend, struct timeval subtractor) {
/*---------------------------------------------------------------------------
The difference in seconds between two times in "timeval" format.
----------------------------------------------------------------------------*/
- return( (subtrahend.tv_sec - subtractor.tv_sec)
- + (subtrahend.tv_usec - subtractor.tv_usec) / 1E6 );
+ return (subtrahend.tv_sec - subtractor.tv_sec)
+ + (subtrahend.tv_usec - subtractor.tv_usec) / 1E6;
}
static struct timeval
-time_inc(struct timeval addend, float increment) {
+time_inc(struct timeval addend, double increment) {
/*----------------------------------------------------------------------------
The time, in "timeval" format, which is <increment> seconds after
the time <addend>. Of course, <increment> may be negative.
@@ -199,7 +203,7 @@ time_inc(struct timeval addend, float increment) {
newtime.tv_usec -= 1E6;
newtime.tv_sec += 1;
}
- return(newtime);
+ return newtime;
}
@@ -223,39 +227,41 @@ hw_clock_is_utc(const bool utc, const bool local_opt,
-static void
-read_adjtime(struct adjtime *adjtime_p, int *rc_p) {
+static int
+read_adjtime(struct adjtime *adjtime_p) {
/*----------------------------------------------------------------------------
Read the adjustment parameters out of the /etc/adjtime file.
Return them as the adjtime structure <*adjtime_p>.
-
If there is no /etc/adjtime file, return defaults.
If values are missing from the file, return defaults for them.
- return *rc_p = 0 if all OK, !=0 otherwise.
+ return value 0 if all OK, !=0 otherwise.
-----------------------------------------------------------------------------*/
FILE *adjfile;
int rc; /* local return code */
struct stat statbuf; /* We don't even use the contents of this. */
- rc = stat(ADJPATH, &statbuf);
- if (rc < 0 && errno == ENOENT) {
- /* He doesn't have a adjtime file, so we'll use defaults. */
- adjtime_p->drift_factor = 0;
- adjtime_p->last_adj_time = 0;
- adjtime_p->not_adjusted = 0;
- adjtime_p->last_calib_time = 0;
- adjtime_p->local_utc = UNKNOWN;
+ rc = stat(ADJPATH, &statbuf);
+ if (rc < 0 && errno == ENOENT) {
+ /* He doesn't have a adjtime file, so we'll use defaults. */
+ adjtime_p->drift_factor = 0;
+ adjtime_p->last_adj_time = 0;
+ adjtime_p->not_adjusted = 0;
+ adjtime_p->last_calib_time = 0;
+ adjtime_p->local_utc = UNKNOWN;
+
+ return 0;
+ }
- *rc_p = 0;
- } else {
adjfile = fopen(ADJPATH, "r"); /* open file for reading */
if (adjfile == NULL) {
outsyserr("cannot open file " ADJPATH);
- *rc_p = 2;
- } else {
+ return EX_OSFILE;
+ }
+
+ {
char line1[81]; /* String: first line of adjtime file */
char line2[81]; /* String: second line of adjtime file */
char line3[81]; /* String: third line of adjtime file */
@@ -277,7 +283,7 @@ read_adjtime(struct adjtime *adjtime_p, int *rc_p) {
adjtime_p->last_calib_time = 0;
timeval = 0;
- sscanf(line1, "%f %ld %f",
+ sscanf(line1, "%lf %ld %lf",
&adjtime_p->drift_factor,
&timeval,
&adjtime_p->not_adjusted);
@@ -299,8 +305,6 @@ read_adjtime(struct adjtime *adjtime_p, int *rc_p) {
fprintf(stderr, _("(Expected: `UTC' or `LOCAL' or nothing.)\n"));
}
}
-
- *rc_p = 0;
}
adjtime_p->dirty = FALSE;
@@ -313,12 +317,13 @@ read_adjtime(struct adjtime *adjtime_p, int *rc_p) {
(adjtime_p->local_utc == LOCAL) ? _("local") :
(adjtime_p->local_utc == UTC) ? _("UTC") : _("unknown"));
}
- }
+
+ return 0;
}
-static void
-synchronize_to_clock_tick(int *retcode_p) {
+static int
+synchronize_to_clock_tick(void) {
/*-----------------------------------------------------------------------------
Wait until the falling edge of the Hardware Clock's update flag so
that any time that is read from the clock immediately after we
@@ -330,14 +335,17 @@ synchronize_to_clock_tick(int *retcode_p) {
We wait (up to one second) either blocked waiting for an rtc device
or in a CPU spin loop. The former is probably not very accurate.
- Return *retcode_p == 0 if it worked, nonzero if it didn't.
-
+ Return 0 if it worked, nonzero if it didn't.
-----------------------------------------------------------------------------*/
- if (debug) printf(_("Waiting for clock tick...\n"));
+ int rc;
- *retcode_p = ur->synchronize_to_clock_tick();
+ if (debug) printf(_("Waiting for clock tick...\n"));
- if (debug) printf(_("...got clock tick\n"));
+ rc = ur->synchronize_to_clock_tick();
+
+ if (debug) printf(_("...got clock tick\n"));
+
+ return rc;
}
@@ -520,7 +528,7 @@ set_hardware_clock_exact(const time_t settime,
static void
display_time(const bool hclock_valid, const time_t systime,
- const float sync_duration) {
+ const double 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
@@ -638,7 +646,7 @@ interpret_date_string(const char *date_opt, time_t * const time_p) {
}
fclose(date_child_fp);
- return(retcode);
+ return retcode;
}
@@ -663,7 +671,7 @@ set_system_clock(const bool hclock_valid, const time_t newtime,
int retcode;
if (!hclock_valid) {
- fprintf(stderr,_("The Hardware Clock does not contain a valid time, so "
+ fprintf(stderr, _("The Hardware Clock does not contain a valid time, so "
"we cannot set the System Time from it.\n"));
retcode = 1;
} else {
@@ -685,10 +693,10 @@ set_system_clock(const bool hclock_valid, const time_t newtime,
#endif
if (debug) {
- printf( _("Calling settimeofday:\n") );
- printf( _("\ttv.tv_sec = %ld, tv.tv_usec = %ld\n"),
- (long) tv.tv_sec, (long) tv.tv_usec );
- printf( _("\ttz.tz_minuteswest = %d\n"), minuteswest);
+ printf(_("Calling settimeofday:\n"));
+ printf(_("\ttv.tv_sec = %ld, tv.tv_usec = %ld\n"),
+ (long) tv.tv_sec, (long) tv.tv_usec);
+ printf(_("\ttz.tz_minuteswest = %d\n"), minuteswest);
}
if (testing) {
printf(_("Not setting system clock because running in test mode.\n"));
@@ -697,85 +705,130 @@ set_system_clock(const bool hclock_valid, const time_t newtime,
const struct timezone tz = { minuteswest, 0 };
rc = settimeofday(&tv, &tz);
- if (rc != 0) {
- if (errno == EPERM)
- fprintf(stderr, _("Must be superuser to set system clock.\n"));
- else
- outsyserr(_("settimeofday() failed"));
- retcode = 1;
+ if (rc) {
+ if (errno == EPERM) {
+ fprintf(stderr,
+ _("Must be superuser to set system clock.\n"));
+ retcode = EX_NOPERM;
+ } else {
+ outsyserr(_("settimeofday() failed"));
+ retcode = 1;
+ }
} else retcode = 0;
}
}
- return(retcode);
+ return retcode;
}
static void
adjust_drift_factor(struct adjtime *adjtime_p,
const time_t nowtime,
- const bool hclock_valid, const time_t hclocktime ) {
-/*---------------------------------------------------------------------------
+ const bool hclock_valid,
+ const time_t hclocktime,
+ const double sync_delay) {
+/*------------------------------------------------------------------------
Update the drift factor in <*adjtime_p> to reflect the fact that the
Hardware Clock was calibrated to <nowtime> and before that was set
to <hclocktime>.
- We assume that the user has been doing regular drift adjustments
- using the drift factor in the adjtime file, so if <nowtime> and
- <clocktime> are different, that means the adjustment factor isn't
- quite right.
-
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 (!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 if (adjtime_p->last_calib_time != 0) {
- const float factor_adjust =
- ((float) (nowtime - hclocktime)
- / (hclocktime - adjtime_p->last_calib_time))
- * 24 * 60 * 60;
-
- if (debug)
- printf(_("Clock drifted %d seconds in the past %d seconds "
- "in spite of a drift factor of %f seconds/day.\n"
- "Adjusting drift factor by %f seconds/day\n"),
- (int) (nowtime - hclocktime),
- (int) (hclocktime - adjtime_p->last_calib_time),
- adjtime_p->drift_factor,
- factor_adjust );
+ ------------------------------------------------------------------------*/
+ if (!hclock_valid) {
+ if (debug)
+ printf(_("Not adjusting drift factor because the "
+ "Hardware Clock previously contained "
+ "garbage.\n"));
+ } else if (adjtime_p->last_calib_time == 0) {
+ if (debug)
+ printf(_("Not adjusting drift factor because last "
+ "calibration time is zero,\n"
+ "so history is bad and calibration startover "
+ "is necessary.\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 if (adjtime_p->last_calib_time != 0) {
+ /*
+ * At adjustment time we adjust the hardware clock according
+ * to the contents of /etc/adjtime.
+ *
+ * At calibration time we set the hardware clock and
+ * update /etc/adjtime, that is, for each calibration
+ * (except the first) we also do an adjustment.
+ *
+ * We are now at calibration time.
+ *
+ * Let us do computation in doubles. (Floats almost suffice,
+ * but 195 days + 1 second equals 195 days in floats.)
+ */
+ const double sec_per_day = 24.0 * 60.0 * 60.0;
+ double atime_per_htime;
+ double adj_days, cal_days;
+ double exp_drift, unc_drift;
+ double factor_adjust;
+
+ /* Adjusted time units per hardware time unit */
+ atime_per_htime = 1.0 + adjtime_p->drift_factor / sec_per_day;
+
+ /* Days since last adjustment (in hardware clock time) */
+ adj_days = (double)(hclocktime - adjtime_p->last_adj_time)
+ / sec_per_day;
+
+ /* Expected drift (sec) since last adjustment */
+ exp_drift = adj_days * adjtime_p->drift_factor
+ + adjtime_p->not_adjusted;
+
+ /* Uncorrected drift (sec) since last calibration */
+ unc_drift = (double)(nowtime - hclocktime)
+ + sync_delay - exp_drift;
+
+ /* Days since last calibration (in hardware clock time) */
+ cal_days = ((double)(adjtime_p->last_adj_time
+ - adjtime_p->last_calib_time)
+ + adjtime_p->not_adjusted)
+ / (sec_per_day * atime_per_htime) + adj_days;
+
+ /* Amount to add to previous drift factor */
+ factor_adjust = unc_drift / cal_days;
+
+ if (debug)
+ printf(_("Clock drifted %.1f seconds in the past "
+ "%d seconds in spite of a drift factor of "
+ "%f seconds/day.\n"
+ "Adjusting drift factor by %f seconds/day\n"),
+ unc_drift,
+ (int) (nowtime - adjtime_p->last_calib_time),
+ adjtime_p->drift_factor,
+ factor_adjust);
- adjtime_p->drift_factor += factor_adjust;
- }
- adjtime_p->last_calib_time = nowtime;
+ adjtime_p->drift_factor += factor_adjust;
+ }
+ adjtime_p->last_calib_time = nowtime;
- adjtime_p->last_adj_time = nowtime;
+ adjtime_p->last_adj_time = nowtime;
- adjtime_p->not_adjusted = 0;
+ adjtime_p->not_adjusted = 0;
- adjtime_p->dirty = TRUE;
+ adjtime_p->dirty = TRUE;
}
static void
-calculate_adjustment(
- const float factor,
+calculate_adjustment(const double factor,
const time_t last_time,
- const float not_adjusted,
+ const double not_adjusted,
const time_t systime,
int *adjustment_p,
- float *retro_p,
+ double *retro_p,
const int debug ) {
/*----------------------------------------------------------------------------
Do the drift adjustment calculation.
@@ -790,13 +843,13 @@ calculate_adjustment(
advance the clock or insert seconds. Negative means to retard the clock
or remove seconds.
----------------------------------------------------------------------------*/
- float exact_adjustment;
+ double exact_adjustment;
- exact_adjustment = ((float) (systime - last_time)) * factor / (24 * 60 * 60)
+ exact_adjustment = ((double) (systime - last_time)) * factor / (24 * 60 * 60)
+ not_adjusted;
*adjustment_p = FLOOR(exact_adjustment);
- *retro_p = exact_adjustment - (float) *adjustment_p;
+ *retro_p = exact_adjustment - (double) *adjustment_p;
if (debug) {
printf (_("Time since last adjustment is %d seconds\n"),
(int) (systime - last_time));
@@ -897,10 +950,18 @@ do_adjustment(struct adjtime *adjtime_p,
if (!hclock_valid) {
fprintf(stderr, _("The Hardware Clock does not contain a valid time, "
"so we cannot adjust it.\n"));
+ adjtime_p->last_calib_time = 0; /* calibration startover is required */
+ adjtime_p->last_adj_time = 0;
+ adjtime_p->not_adjusted = 0;
+ adjtime_p->dirty = TRUE;
+ } else if (adjtime_p->last_adj_time == 0) {
+ if (debug)
+ printf("Not setting clock because last adjustment time is zero, "
+ "so history is bad.");
} else {
int adjustment;
/* Number of seconds we must insert in the Hardware Clock */
- float retro;
+ double retro;
/* Fraction of second we have to remove from clock after inserting
<adjustment> whole seconds.
*/
@@ -951,13 +1012,13 @@ determine_clock_access_method(const bool user_requests_ISA) {
}
}
-static void
+static int
manipulate_clock(const bool show, const bool adjust, const bool noadjfile,
const bool set, const time_t set_time,
const bool hctosys, const bool systohc,
const struct timeval startup_time,
const bool utc, const bool local_opt,
- const bool testing, int *retcode_p) {
+ const bool testing) {
/*---------------------------------------------------------------------------
Do all the normal work of hwclock - read, set clock, etc.
@@ -965,24 +1026,26 @@ manipulate_clock(const bool show, const bool adjust, const bool noadjfile,
Return rc == 0 if everything went OK, rc != 0 if not.
----------------------------------------------------------------------------*/
- struct adjtime adjtime;
- /* Contents of the adjtime file, or what they should be. */
- int rc; /* local return code */
- bool no_auth; /* User lacks necessary authorization to access the clock */
-
- no_auth = ur->get_permissions();
-
- if (no_auth) *retcode_p = 1;
- else {
- if (!noadjfile && (adjust || set || systohc || (!utc && !local_opt)))
- read_adjtime(&adjtime, &rc);
- else {
+ struct adjtime adjtime;
+ /* Contents of the adjtime file, or what they should be. */
+ int rc; /* local return code */
+ bool no_auth; /* User lacks necessary authorization to access the clock */
+
+ no_auth = ur->get_permissions();
+ if (no_auth)
+ return EX_NOPERM;
+
+ if (!noadjfile && (adjust || set || systohc || (!utc && !local_opt))) {
+ rc = read_adjtime(&adjtime);
+ if (rc)
+ return rc;
+ } else {
/* A little trick to avoid reading the file if we don't have to */
adjtime.dirty = FALSE;
rc = 0;
}
- if (rc != 0) *retcode_p = 2;
- else {
+
+ {
const bool universal = hw_clock_is_utc(utc, local_opt, adjtime);
if ((set || systohc || adjust) &&
@@ -991,9 +1054,11 @@ manipulate_clock(const bool show, const bool adjust, const bool noadjfile,
adjtime.dirty = TRUE;
}
- synchronize_to_clock_tick(retcode_p);
- /* this takes up to 1 second */
- if (*retcode_p == 0) {
+ rc = synchronize_to_clock_tick(); /* this takes up to 1 second */
+ if (rc)
+ return rc;
+
+ {
struct timeval read_time;
/* The time at which we read the Hardware Clock */
@@ -1014,16 +1079,14 @@ manipulate_clock(const bool show, const bool adjust, const bool noadjfile,
if (show) {
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,
universal, testing);
- adjust_drift_factor(&adjtime, set_time, hclock_valid, hclocktime);
- *retcode_p = 0;
+ adjust_drift_factor(&adjtime, set_time, hclock_valid, hclocktime,
+ time_diff(read_time, startup_time));
} else if (adjust) {
do_adjustment(&adjtime, hclock_valid, hclocktime,
read_time, universal, testing);
- *retcode_p = 0;
} else if (systohc) {
struct timeval nowtime, reftime;
/* We can only set_hardware_clock_exact to a whole seconds
@@ -1036,22 +1099,20 @@ manipulate_clock(const bool show, const bool adjust, const bool noadjfile,
set_hardware_clock_exact((time_t) reftime.tv_sec, reftime,
universal, testing);
- *retcode_p = 0;
adjust_drift_factor(&adjtime, (time_t) reftime.tv_sec, hclock_valid,
- hclocktime);
+ hclocktime, (double) read_time.tv_usec / 1E6);
} else if (hctosys) {
rc = set_system_clock(hclock_valid, hclocktime, testing);
- if (rc != 0) {
+ if (rc) {
printf(_("Unable to set system clock.\n"));
- *retcode_p = 1;
- } else *retcode_p = 0;
+ return rc;
+ }
}
- if (!noadjfile) {
+ if (!noadjfile)
save_adjtime(adjtime, testing);
- }
}
}
- }
+ return 0;
}
@@ -1104,6 +1165,11 @@ manipulate_epoch(const bool getepoch, const bool setepoch,
#define RTC_DEV "/dev/rtc"
#endif
+static void
+out_version(void) {
+ printf(_("%s from %s\n"), MYNAME, util_linux_version);
+}
+
/*
usage - Output (error and) usage information
@@ -1148,7 +1214,7 @@ usage( const char *fmt, ... ) {
" either --utc or --localtime\n"
),RTC_DEV);
#ifdef __alpha__
- fprintf( usageto, _(
+ fprintf(usageto, _(
" --jensen, --arc, --srm, --funky-toy\n"
" tell hwclock the type of alpha you have (see hwclock(8))\n"
) );
@@ -1156,200 +1222,272 @@ usage( const char *fmt, ... ) {
fflush(stdout);
- if( fmt ) {
+ if (fmt) {
usageto = stderr;
va_start(ap, fmt);
vfprintf(stderr, fmt, ap);
va_end(ap);
}
- exit( fmt ? 99 : 0 );
+ exit(fmt ? EX_USAGE : 0);
}
+static const struct option longopts[] = {
+ { "adjust", 0, 0, 'a' },
+ { "help", 0, 0, 'h' },
+ { "show", 0, 0, 'r' },
+ { "hctosys", 0, 0, 's' },
+ { "utc", 0, 0, 'u' },
+ { "version", 0, 0, 'v' },
+ { "systohc", 0, 0, 'w' },
+ { "debug", 0, 0, 'D' },
+#ifdef __alpha__
+ { "ARC", 0, 0, 'A' },
+ { "arc", 0, 0, 'A' },
+ { "Jensen", 0, 0, 'J' },
+ { "jensen", 0, 0, 'J' },
+ { "SRM", 0, 0, 'S' },
+ { "srm", 0, 0, 'S' },
+ { "funky-toy", 0, 0, 'F'}
+#endif
+ { "set", 0, 0, 128 },
+ { "getepoch", 0, 0, 129 },
+ { "setepoch", 0, 0, 130 },
+ { "noadjfile", 0, 0, 131 },
+ { "localtime", 0, 0, 132 },
+ { "badyear", 0, 0, 133 },
+ { "directisa", 0, 0, 134 },
+ { "test", 0, 0, 135 },
+ { "date", 1, 0, 136 },
+ { "epoch", 1, 0, 137 },
+ { NULL, 0, 0, 0 }
+};
+
+/*
+ * Returns:
+ * EX_USAGE: bad invocation
+ * EX_NOPERM: no permission
+ * EX_OSFILE: cannot open /dev/rtc or /etc/adjtime
+ * EX_IOERR: ioctl error getting or setting the time
+ * 0: OK (or not)
+ * 1: failure
+ */
int
main(int argc, char **argv) {
- struct timeval startup_time;
- /* The time we started up, in seconds into the epoch, including fractions.
- */
- time_t set_time; /* Time to which user said to set Hardware Clock */
+ struct timeval startup_time;
+ /* The time we started up, in seconds into the epoch, including
+ fractions. */
+ time_t set_time; /* Time to which user said to set Hardware Clock */
- bool permitted; /* User is permitted to do the function */
- int retcode; /* Our eventual return code */
+ bool permitted; /* User is permitted to do the function */
+ int rc, c;
- int rc; /* local return code */
+ /* Variables set by various options; show may also be set later */
+ /* The options debug, badyear and epoch_option are global */
+ bool show, set, systohc, hctosys, adjust, getepoch, setepoch;
+ bool utc, testing, local_opt, noadjfile, directisa;
+ bool ARCconsole, Jensen, SRM, funky_toy;
+ char *date_opt;
- /* option_def is the control table for the option parser. These other
- variables are the results of parsing the options and their meanings
- are given by the option_def. The only exception is <show>, which
- may be modified after parsing is complete to effect an implied option.
- */
- bool help, show, set, systohc, hctosys, adjust, getepoch, setepoch, version;
- bool ARCconsole, utc, testing, directisa, Jensen, SRM, funky_toy, noadjfile;
- bool local_opt;
- char *date_opt;
-
- const optStruct option_def[] = {
- { 'h', (char *) "help", OPT_FLAG, &help, 0 },
- { 'r', (char *) "show", OPT_FLAG, &show, 0 },
- { 0, (char *) "set", OPT_FLAG, &set, 0 },
- { 'w', (char *) "systohc", OPT_FLAG, &systohc, 0 },
- { 's', (char *) "hctosys", OPT_FLAG, &hctosys, 0 },
- { 0, (char *) "getepoch", OPT_FLAG, &getepoch, 0 },
- { 0, (char *) "setepoch", OPT_FLAG, &setepoch, 0 },
- { 'a', (char *) "adjust", OPT_FLAG, &adjust, 0 },
- { 0, (char *) "noadjfile", OPT_FLAG, &noadjfile, 0 },
- { 'v', (char *) "version", OPT_FLAG, &version, 0 },
- { 'V', (char *) "version", OPT_FLAG, &version, 0 },
- { 0, (char *) "date", OPT_STRING, &date_opt, 0 },
- { 0, (char *) "epoch", OPT_UINT, &epoch_option,0 },
- { 'u', (char *) "utc", OPT_FLAG, &utc, 0 },
- { 0, (char *) "localtime", OPT_FLAG, &local_opt, 0 },
- { 0, (char *) "badyear", OPT_FLAG, &badyear, 0 },
- { 0, (char *) "directisa", OPT_FLAG, &directisa, 0 },
- { 0, (char *) "test", OPT_FLAG, &testing, 0 },
- { 'D', (char *) "debug", OPT_FLAG, &debug, 0 },
-#ifdef __alpha__
- { 'A', (char *) "ARC", OPT_FLAG, &ARCconsole,0 },
- { 'A', (char *) "arc", OPT_FLAG, &ARCconsole,0 },
- { 'J', (char *) "Jensen", OPT_FLAG, &Jensen, 0 },
- { 'J', (char *) "jensen", OPT_FLAG, &Jensen, 0 },
- { 'S', (char *) "SRM", OPT_FLAG, &SRM, 0 },
- { 'S', (char *) "srm", OPT_FLAG, &SRM, 0 },
- { 'F', (char *) "funky-toy", OPT_FLAG, &funky_toy, 0 },
-#endif
- { 0, (char *) NULL, OPT_END, NULL, 0 }
- };
- int argc_parse; /* argc, except we modify it as we parse */
- char **argv_parse; /* argv, except we modify it as we parse */
+ /* Remember what time we were invoked */
+ gettimeofday(&startup_time, NULL);
- gettimeofday(&startup_time, NULL); /* Remember what time we were invoked */
-
- setlocale(LC_ALL, "");
+ setlocale(LC_ALL, "");
#ifdef LC_NUMERIC
- /* We need LC_CTYPE and LC_TIME and LC_MESSAGES, but must avoid
- LC_NUMERIC since it gives problems when we write to /etc/adjtime.
- - gqueri@mail.dotcom.fr */
- setlocale(LC_NUMERIC, "C");
+ /* We need LC_CTYPE and LC_TIME and LC_MESSAGES, but must avoid
+ LC_NUMERIC since it gives problems when we write to /etc/adjtime.
+ - gqueri@mail.dotcom.fr */
+ setlocale(LC_NUMERIC, "C");
#endif
- bindtextdomain(PACKAGE, LOCALEDIR);
- textdomain(PACKAGE);
-
- /* set option defaults */
- help = show = set = systohc = hctosys = adjust = noadjfile =
- getepoch = setepoch = version = utc = local_opt =
- ARCconsole = SRM = funky_toy = directisa = badyear = Jensen =
- testing = debug = FALSE;
- date_opt = NULL;
-
- argc_parse = argc; argv_parse = argv;
- optParseOptions(&argc_parse, argv_parse, option_def, 0);
- /* Uses and sets argc_parse, argv_parse.
- Sets show, systohc, hctosys, adjust, utc, local_opt, version,
- testing, debug, set, date_opt, getepoch, setepoch, epoch_option,
- noadjtime */
- /* This is an ugly routine - for example, if I give an incorrect
- option, it only says "unrecognized option" without telling
- me what options are recognized. Rewrite with standard
- getopt() and usage() and throw shhopt out. */
-
- if (argc_parse - 1 > 0) {
- usage( _("%s takes no non-option arguments. "
- "You supplied %d.\n"),
- MYNAME, argc_parse - 1);
- }
+ bindtextdomain(PACKAGE, LOCALEDIR);
+ textdomain(PACKAGE);
+
+ /* Set option defaults */
+ show = set = systohc = hctosys = adjust = noadjfile = FALSE;
+ getepoch = setepoch = utc = local_opt = testing = debug = FALSE;
+ ARCconsole = Jensen = SRM = funky_toy = directisa = badyear = FALSE;
+ date_opt = NULL;
+
+ while ((c = getopt_long (argc, argv, "?hvVDarsuwAJSF", longopts, NULL))
+ != -1) {
+ switch (c) {
+ case 'D':
+ debug = TRUE;
+ break;
+ case 'a':
+ adjust = TRUE;
+ break;
+ case 'r':
+ show = TRUE;
+ break;
+ case 's':
+ hctosys = TRUE;
+ break;
+ case 'u':
+ utc = TRUE;
+ break;
+ case 'w':
+ systohc = TRUE;
+ break;
+#ifdef __alpha__
+ case 'A':
+ ARCconsole = TRUE;
+ break;
+ case 'J':
+ Jensen = TRUE;
+ break;
+ case 'S':
+ SRM = TRUE;
+ break;
+ case 'F':
+ funky_toy = TRUE;
+ break;
+#endif
+ case 128:
+ set = TRUE;
+ break;
+ case 129:
+ getepoch = TRUE;
+ break;
+ case 130:
+ setepoch = TRUE;
+ break;
+ case 131:
+ noadjfile = TRUE;
+ break;
+ case 132:
+ local_opt = TRUE; /* --localtime */
+ break;
+ case 133:
+ badyear = TRUE;
+ break;
+ case 134:
+ directisa = TRUE;
+ break;
+ case 135:
+ testing = TRUE; /* --test */
+ break;
+ case 136:
+ date_opt = optarg; /* --date */
+ break;
+ case 137:
+ epoch_option = atoi(optarg); /* --epoch */
+ break;
+ case 'v': /* --version */
+ case 'V':
+ out_version();
+ return 0;
+ case 'h': /* --help */
+ case '?':
+ default:
+ usage(NULL);
+ }
+ }
- if (help)
- usage( NULL );
+ argc -= optind;
+ argv += optind;
- if (show + set + systohc + hctosys + adjust +
- getepoch + setepoch + version > 1) {
- fprintf(stderr, _("You have specified multiple function options.\n"
- "You can only perform one function at a time.\n"));
- exit(100);
- }
+ if (argc > 0) {
+ usage(_("%s takes no non-option arguments. "
+ "You supplied %d.\n"),
+ MYNAME, argc);
+ }
- if (utc && local_opt) {
- fprintf(stderr, _("%s: The --utc and --localtime options are mutually "
- "exclusive. You specified both.\n"), MYNAME);
- exit(100);
- }
+ if (show + set + systohc + hctosys + adjust + getepoch + setepoch > 1){
+ fprintf(stderr, _("You have specified multiple functions.\n"
+ "You can only perform one function "
+ "at a time.\n"));
+ exit(EX_USAGE);
+ }
- if (adjust && noadjfile) {
- fprintf(stderr, _("%s: The --adjust and --noadjfile options are mutually "
- "exclusive. You specified both.\n"), MYNAME);
- exit(100);
- }
+ if (utc && local_opt) {
+ fprintf(stderr, _("%s: The --utc and --localtime options "
+ "are mutually exclusive. You specified "
+ "both.\n"), MYNAME);
+ exit(EX_USAGE);
+ }
- if (noadjfile && !(utc || local_opt)) {
- fprintf(stderr, _("%s: With --noadjfile, you must specify either "
- "--utc or --localtime\n"), MYNAME);
- exit(100);
- }
+ if (adjust && noadjfile) {
+ fprintf(stderr, _("%s: The --adjust and --noadjfile options "
+ "are mutually exclusive. You specified "
+ "both.\n"), MYNAME);
+ exit(EX_USAGE);
+ }
+
+ if (noadjfile && !(utc || local_opt)) {
+ fprintf(stderr, _("%s: With --noadjfile, you must specify "
+ "either --utc or --localtime\n"), MYNAME);
+ exit(EX_USAGE);
+ }
#ifdef __alpha__
- set_cmos_epoch(ARCconsole, SRM);
- set_cmos_access(Jensen, funky_toy);
+ set_cmos_epoch(ARCconsole, SRM);
+ set_cmos_access(Jensen, funky_toy);
#endif
- if (set) {
- rc = interpret_date_string(date_opt, &set_time); /* (time-consuming) */
- if (rc != 0) {
- fprintf(stderr, _("No usable set-to time. Cannot set clock.\n"));
- exit(100);
- }
- }
+ if (set) {
+ rc = interpret_date_string(date_opt, &set_time);
+ /* (time-consuming) */
+ if (rc != 0) {
+ fprintf(stderr, _("No usable set-to time. "
+ "Cannot set clock.\n"));
+ exit(EX_USAGE);
+ }
+ }
- if (!(show | set | systohc | hctosys | adjust | getepoch | setepoch |
- version))
- show = 1; /* default to show */
+ if (!(show | set | systohc | hctosys | adjust | getepoch | setepoch))
+ show = 1; /* default to show */
- if (getuid() == 0) permitted = TRUE;
- else {
- /* program is designed to run setuid (in some situations) -- be secure! */
- if (set || hctosys || systohc || adjust) {
- fprintf(stderr,
- _("Sorry, only the superuser can change the Hardware Clock.\n"));
- permitted = FALSE;
- } else if (hctosys) {
- fprintf(stderr,
- _("Sorry, only the superuser can change the System Clock.\n"));
- permitted = FALSE;
- } else if (setepoch) {
- fprintf(stderr,
- _("Sorry, only the superuser can change "
- "the Hardware Clock epoch in the kernel.\n"));
- permitted = FALSE;
- } else
- permitted = TRUE;
- }
+ if (getuid() == 0)
+ permitted = TRUE;
+ else {
+ /* program is designed to run setuid (in some situations) */
+ if (set || hctosys || systohc || adjust) {
+ fprintf(stderr,
+ _("Sorry, only the superuser can change "
+ "the Hardware Clock.\n"));
+ permitted = FALSE;
+ } else if (hctosys) {
+ fprintf(stderr,
+ _("Sorry, only the superuser can change "
+ "the System Clock.\n"));
+ permitted = FALSE;
+ } else if (setepoch) {
+ fprintf(stderr,
+ _("Sorry, only the superuser can change the "
+ "Hardware Clock epoch in the kernel.\n"));
+ permitted = FALSE;
+ } else
+ permitted = TRUE;
+ }
- if (!permitted) retcode = 2;
- else {
- retcode = 0;
- if (version) {
- printf(MYNAME " " VERSION "/%s\n",util_linux_version);
- } else if (getepoch || setepoch) {
- manipulate_epoch(getepoch, setepoch, epoch_option, testing);
- } else {
- if (debug)
- printf(MYNAME " " VERSION "/%s\n",util_linux_version);
- determine_clock_access_method(directisa);
- if (!ur) {
- fprintf(stderr,
- _("Cannot access the Hardware Clock via any known method.\n"));
- if (!debug)
+ if (!permitted)
+ exit(EX_NOPERM);
+
+ if (getepoch || setepoch) {
+ manipulate_epoch(getepoch, setepoch, epoch_option, testing);
+ return 0;
+ }
+
+ if (debug)
+ out_version();
+ determine_clock_access_method(directisa);
+ if (!ur) {
fprintf(stderr,
- _("Use the --debug option to see the details of our "
- "search for an access method.\n"));
- } else
- manipulate_clock(show, adjust, noadjfile, set, set_time,
- hctosys, systohc, startup_time, utc, local_opt,
- testing, &rc);
- }
- }
- exit(retcode);
+ _("Cannot access the Hardware Clock via "
+ "any known method.\n"));
+ if (!debug)
+ fprintf(stderr,
+ _("Use the --debug option to see the details "
+ "of our search for an access method.\n"));
+ exit(1);
+ }
+
+ return manipulate_clock(show, adjust, noadjfile, set, set_time,
+ hctosys, systohc, startup_time, utc,
+ local_opt, testing);
}
/* A single routine for greater uniformity */
diff --git a/hwclock/kd.c b/hwclock/kd.c
index f3327e1cc..dbbe758f4 100644
--- a/hwclock/kd.c
+++ b/hwclock/kd.c
@@ -1,6 +1,7 @@
/* kd.c - KDGHWCLK stuff, possibly m68k only */
#include <unistd.h> /* for close() */
#include <fcntl.h> /* for O_RDONLY */
+#include <sysexits.h>
#include <sys/ioctl.h>
#include "../defines.h" /* for HAVE_nanosleep */
@@ -90,7 +91,7 @@ read_hardware_clock_kd(struct tm *tm) {
if (ioctl(con_fd, KDGHWCLK, &t) == -1) {
outsyserr(_("ioctl() failed to read time from %s"), con_fd_filename);
- exit(5);
+ exit(EX_IOERR);
}
tm->tm_sec = t.sec;
diff --git a/hwclock/rtc.c b/hwclock/rtc.c
index 2694d8663..f6fb0186e 100644
--- a/hwclock/rtc.c
+++ b/hwclock/rtc.c
@@ -1,6 +1,7 @@
/* rtc.c - Use /dev/rtc for clock access */
#include <unistd.h> /* for close() */
#include <fcntl.h> /* for O_RDONLY */
+#include <sysexits.h>
#include <sys/ioctl.h>
#include "clock.h"
@@ -90,17 +91,29 @@ struct linux_rtc_time {
static char rtc_dev_name[40];
-/* maybe we should not try /dev/misc/efirtc?
- maybe we should reset rtc_dev_name to give better error messages */
+/* maybe we should not try /dev/misc/efirtc? */
static int
open_rtc(void) {
int rtc_fd;
sprintf(rtc_dev_name, "/dev/%s", RTC_DEVN);
rtc_fd = open(rtc_dev_name, O_RDONLY);
- if (rtc_fd < 0) {
+ if (rtc_fd < 0 && errno == ENOENT) {
sprintf(rtc_dev_name, "/dev/misc/%s", RTC_DEVN);
rtc_fd = open(rtc_dev_name, O_RDONLY);
+ if (rtc_fd < 0 && errno == ENOENT)
+ sprintf(rtc_dev_name, "/dev/%s", RTC_DEVN);
+ }
+ return rtc_fd;
+}
+
+static int
+open_rtc_or_exit(void) {
+ int rtc_fd = open_rtc();
+
+ if (rtc_fd < 0) {
+ outsyserr(_("open() of %s failed"), rtc_dev_name);
+ exit(EX_OSFILE);
}
return rtc_fd;
}
@@ -135,7 +148,7 @@ do_rtc_read_ioctl(int rtc_fd, struct tm *tm) {
perror(ioctlname);
fprintf(stderr, _("ioctl() to %s to read the time failed.\n"),
rtc_dev_name);
- exit(5);
+ exit(EX_IOERR);
}
tm->tm_isdst = -1; /* don't know whether it's dst */
@@ -204,7 +217,7 @@ int ret;
#else
rc = ioctl(rtc_fd, RTC_UIE_ON, 0);
#endif
- if (rc == -1 && errno == EINVAL) {
+ if (rc == -1 && (errno == ENOTTY || errno == EINVAL)) {
/* This rtc device doesn't have interrupt functions. This is typical
on an Alpha, where the Hardware Clock interrupts are used by the
kernel for the system clock, so aren't at the user's disposal.
@@ -245,11 +258,7 @@ static int
read_hardware_clock_rtc(struct tm *tm) {
int rtc_fd;
- rtc_fd = open_rtc();
- if (rtc_fd == -1) {
- outsyserr(_("open() of %s failed"), rtc_dev_name);
- exit(5);
- }
+ rtc_fd = open_rtc_or_exit();
/* Read the RTC time/date, return answer via tm */
do_rtc_read_ioctl(rtc_fd, tm);
@@ -269,11 +278,8 @@ set_hardware_clock_rtc(const struct tm *new_broken_time) {
int rtc_fd;
char *ioctlname;
- rtc_fd = open_rtc();
- if (rtc_fd < 0) {
- outsyserr(_("Unable to open %s"), rtc_dev_name);
- exit(5);
- }
+ rtc_fd = open_rtc_or_exit();
+
#ifdef __sparc__
{
struct sparc_rtc_time stm;
@@ -299,7 +305,7 @@ set_hardware_clock_rtc(const struct tm *new_broken_time) {
perror(ioctlname);
fprintf(stderr, _("ioctl() to %s to set the time failed.\n"),
rtc_dev_name);
- exit(5);
+ exit(EX_IOERR);
}
if (debug)
diff --git a/hwclock/shhopt-1.1.lsm b/hwclock/shhopt-1.1.lsm
deleted file mode 100644
index a61a26969..000000000
--- a/hwclock/shhopt-1.1.lsm
+++ /dev/null
@@ -1,17 +0,0 @@
-Begin3
-Title: shhopt - library for parsing command line options.
-Version: 1.1
-Entered-date: 06JUN96
-Description: C-functions for parsing command line options, both
- traditional one-character options, and GNU'ish
- --long-options.
-Keywords: programming, library, lib, commandline
-Author: sverrehu@ifi.uio.no (Sverre H. Huseby)
-Primary-site: sunsite.unc.edu /pub/Linux/libs
- shhopt-1.1.tar.gz
-Platforms: Requires ANSI C-compiler.
-Copying-policy: BeerWare: If you have the time and money, send me a bottle
- of your favourite beer. If not, just send me a mail or
- something. Copy and use as you wish; just leave the
- author's name where you find it.
-End
diff --git a/hwclock/shhopt.c b/hwclock/shhopt.c
deleted file mode 100644
index ac3412829..000000000
--- a/hwclock/shhopt.c
+++ /dev/null
@@ -1,468 +0,0 @@
-/* $Id: shhopt.c,v 2.2 1997/07/06 23:11:55 aebr Exp $ */
-/**************************************************************************
- *
- * FILE shhopt.c
- *
- * DESCRIPTION Functions for parsing command line arguments. Values
- * of miscellaneous types may be stored in variables,
- * or passed to functions as specified.
- *
- * REQUIREMENTS Some systems lack the ANSI C -function strtoul. If your
- * system is one of those, you'll ned to write one yourself,
- * or get the GNU liberty-library (from prep.ai.mit.edu).
- *
- * WRITTEN BY Sverre H. Huseby <sverrehu@ifi.uio.no>
- *
- **************************************************************************/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <string.h>
-#include <ctype.h>
-#include <limits.h>
-#include <errno.h>
-
-#include "shhopt.h"
-#include "nls.h"
-
-/**************************************************************************
- * *
- * P R I V A T E D A T A *
- * *
- **************************************************************************/
-
-static void optFatalFunc(const char *, ...);
-static void (*optFatal)(const char *format, ...) = optFatalFunc;
-
-
-
-/**************************************************************************
- * *
- * P R I V A T E F U N C T I O N S *
- * *
- **************************************************************************/
-
-/*-------------------------------------------------------------------------
- *
- * NAME optFatalFunc
- *
- * FUNCTION Show given message and abort the program.
- *
- * INPUT format, ...
- * Arguments used as with printf().
- *
- * RETURNS Never returns. The program is aborted.
- *
- */
-void optFatalFunc(const char *format, ...)
-{
- va_list ap;
-
- fflush(stdout);
- va_start(ap, format);
- vfprintf(stderr, format, ap);
- va_end(ap);
- exit(99);
-}
-
-
-
-/*-------------------------------------------------------------------------
- *
- * NAME optStructCount
- *
- * FUNCTION Get number of options in a optStruct.
- *
- * INPUT opt array of possible options.
- *
- * RETURNS Number of options in the given array.
- *
- * DESCRIPTION Count elements in an optStruct-array. The strcture must
- * be ended using an element of type OPT_END.
- *
- */
-static int optStructCount(const optStruct opt[])
-{
- int ret = 0;
-
- while (opt[ret].type != OPT_END)
- ++ret;
- return ret;
-}
-
-
-
-/*-------------------------------------------------------------------------
- *
- * NAME optMatch
- *
- * FUNCTION Find a matching option.
- *
- * INPUT opt array of possible options.
- * s string to match, without `-' or `--'.
- * lng match long option, otherwise short.
- *
- * RETURNS Index to the option if found, -1 if not found.
- *
- * DESCRIPTION Short options are matched from the first character in
- * the given string.
- *
- */
-static int optMatch(const optStruct opt[], const char *s, int lng)
-{
- int nopt, q, matchlen = 0;
- char *p;
-
- nopt = optStructCount(opt);
- if (lng) {
- if ((p = strchr(s, '=')) != NULL)
- matchlen = p - s;
- else
- matchlen = strlen(s);
- }
- for (q = 0; q < nopt; q++) {
- if (lng) {
- if (!opt[q].longName)
- continue;
- if (strncmp(s, opt[q].longName, matchlen) == 0)
- return q;
- } else {
- if (!opt[q].shortName)
- continue;
- if (*s == opt[q].shortName)
- return q;
- }
- }
- return -1;
-}
-
-
-
-/*-------------------------------------------------------------------------
- *
- * NAME optString
- *
- * FUNCTION Return a (static) string with the option name.
- *
- * INPUT opt the option to stringify.
- * lng is it a long option?
- *
- * RETURNS Pointer to static string.
- *
- */
-static char *optString(const optStruct *opt, int lng)
-{
- static char ret[31];
-
- if (lng) {
- strcpy(ret, "--");
- strncpy(ret + 2, opt->longName, 28);
- } else {
- ret[0] = '-';
- ret[1] = opt->shortName;
- ret[2] = '\0';
- }
- return ret;
-}
-
-
-
-/*-------------------------------------------------------------------------
- *
- * NAME optNeedsArgument
- *
- * FUNCTION Check if an option requires an argument.
- *
- * INPUT opt the option to check.
- *
- * RETURNS Boolean value.
- *
- */
-static int optNeedsArgument(const optStruct *opt)
-{
- return opt->type == OPT_STRING
- || opt->type == OPT_INT
- || opt->type == OPT_UINT
- || opt->type == OPT_LONG
- || opt->type == OPT_ULONG;
-}
-
-
-
-/*-------------------------------------------------------------------------
- *
- * NAME argvRemove
- *
- * FUNCTION Remove an entry from an argv-array.
- *
- * INPUT argc pointer to number of options.
- * argv array of option-/argument-strings.
- * i index of option to remove.
- *
- * OUTPUT argc new argument count.
- * argv array with given argument removed.
- *
- */
-static void argvRemove(int *argc, char *argv[], int i)
-{
- if (i >= *argc)
- return;
- while (i++ < *argc)
- argv[i - 1] = argv[i];
- --*argc;
-}
-
-
-
-/*-------------------------------------------------------------------------
- *
- * NAME optExecute
- *
- * FUNCTION Perform the action of an option.
- *
- * INPUT opt array of possible options.
- * arg argument to option, if it applies.
- * lng was the option given as a long option?
- *
- * RETURNS Nothing. Aborts in case of error.
- *
- */
-static void optExecute(const optStruct *opt, char *arg, int lng)
-{
- switch (opt->type) {
- case OPT_FLAG:
- if (opt->flags & OPT_CALLFUNC)
- ((void (*)(void)) opt->arg)();
- else
- *((int *) opt->arg) = 1;
- break;
-
- case OPT_STRING:
- if (opt->flags & OPT_CALLFUNC)
- ((void (*)(char *)) opt->arg)(arg);
- else
- *((char **) opt->arg) = arg;
- break;
-
- case OPT_INT:
- case OPT_LONG: {
- long tmp;
- char *e;
-
- tmp = strtol(arg, &e, 10);
- if (*e)
- optFatal(_("invalid number `%s'\n"), arg);
- if (errno == ERANGE
- || (opt->type == OPT_INT && (tmp > INT_MAX || tmp < INT_MIN)))
- optFatal(_("number `%s' to `%s' out of range\n"),
- arg, optString(opt, lng));
- if (opt->type == OPT_INT) {
- if (opt->flags & OPT_CALLFUNC)
- ((void (*)(int)) opt->arg)((int) tmp);
- else
- *((int *) opt->arg) = (int) tmp;
- } else /* OPT_LONG */ {
- if (opt->flags & OPT_CALLFUNC)
- ((void (*)(long)) opt->arg)(tmp);
- else
- *((long *) opt->arg) = tmp;
- }
- break;
- }
-
- case OPT_UINT:
- case OPT_ULONG: {
- unsigned long tmp;
- char *e;
-
- tmp = strtoul(arg, &e, 10);
- if (*e)
- optFatal(_("invalid number `%s'\n"), arg);
- if (errno == ERANGE
- || (opt->type == OPT_UINT && tmp > UINT_MAX))
- optFatal(_("number `%s' to `%s' out of range\n"),
- arg, optString(opt, lng));
- if (opt->type == OPT_UINT) {
- if (opt->flags & OPT_CALLFUNC)
- ((void (*)(unsigned)) opt->arg)((unsigned) tmp);
- else
- *((unsigned *) opt->arg) = (unsigned) tmp;
- } else /* OPT_ULONG */ {
- if (opt->flags & OPT_CALLFUNC)
- ((void (*)(unsigned long)) opt->arg)(tmp);
- else
- *((unsigned long *) opt->arg) = tmp;
- }
- break;
- }
-
- default:
- break;
- }
-}
-
-
-
-/**************************************************************************
- * *
- * P U B L I C F U N C T I O N S *
- * *
- **************************************************************************/
-
-/*-------------------------------------------------------------------------
- *
- * NAME optSetFatalFunc
- *
- * FUNCTION Set function used to display error message and exit.
- *
- * SYNOPSIS #include "shhmsg.h"
- * void optSetFatalFunc(void (*f)(const char *, ...));
- *
- * INPUT f function accepting printf()'like parameters,
- * that _must_ abort the program.
- *
- */
-void optSetFatalFunc(void (*f)(const char *, ...))
-{
- optFatal = f;
-}
-
-
-
-/*-------------------------------------------------------------------------
- *
- * NAME optParseOptions
- *
- * FUNCTION Parse commandline options.
- *
- * SYNOPSIS #include "shhopt.h"
- * void optParseOptions(int *argc, char *argv[],
- * const optStruct opt[], int allowNegNum);
- *
- * INPUT argc Pointer to number of options.
- * argv Array of option-/argument-strings.
- * opt Array of possible options.
- * allowNegNum
- * a negative number is not to be taken as
- * an option.
- *
- * OUTPUT argc new argument count.
- * argv array with arguments removed.
- *
- * RETURNS Nothing. Aborts in case of error.
- *
- * DESCRIPTION This function checks each option in the argv-array
- * against strings in the opt-array, and `executes' any
- * matching action. Any arguments to the options are
- * extracted and stored in the variables or passed to
- * functions pointed to by entries in opt.
- *
- * Options and arguments used are removed from the argv-
- * array, and argc is decreased accordingly.
- *
- * Any error leads to program abortion.
- *
- */
-void optParseOptions(int *argc, char *argv[],
- const optStruct opt[], int allowNegNum)
-{
- int ai, /* argv index. */
- optarg, /* argv index of option argument, or -1 if none. */
- mi, /* Match index in opt. */
- done;
- char *arg, /* Pointer to argument to an option. */
- *o, /* pointer to an option character */
- *p;
-
- /*
- * Loop through all arguments.
- */
- for (ai = 0; ai < *argc; ) {
- /*
- * "--" indicates that the rest of the argv-array does not
- * contain options.
- */
- if (strcmp(argv[ai], "--") == 0) {
- argvRemove(argc, argv, ai);
- break;
- }
-
- if (allowNegNum && argv[ai][0] == '-' && isdigit(argv[ai][1])) {
- ++ai;
- continue;
- } else if (strncmp(argv[ai], "--", 2) == 0) {
- /* long option */
- /* find matching option */
- if ((mi = optMatch(opt, argv[ai] + 2, 1)) < 0)
- optFatal(_("unrecognized option `%s'\n"), argv[ai]);
-
- /* possibly locate the argument to this option. */
- arg = NULL;
- if ((p = strchr(argv[ai], '=')) != NULL)
- arg = p + 1;
-
- /* does this option take an argument? */
- optarg = -1;
- if (optNeedsArgument(&opt[mi])) {
- /* option needs an argument. find it. */
- if (!arg) {
- if ((optarg = ai + 1) == *argc)
- optFatal(_("option `%s' requires an argument\n"),
- optString(&opt[mi], 1));
- arg = argv[optarg];
- }
- } else {
- if (arg)
- optFatal(_("option `%s' doesn't allow an argument\n"),
- optString(&opt[mi], 1));
- }
- /* perform the action of this option. */
- optExecute(&opt[mi], arg, 1);
- /* remove option and any argument from the argv-array. */
- if (optarg >= 0)
- argvRemove(argc, argv, ai);
- argvRemove(argc, argv, ai);
- } else if (*argv[ai] == '-') {
- /* A dash by itself is not considered an option. */
- if (argv[ai][1] == '\0') {
- ++ai;
- continue;
- }
- /* Short option(s) following */
- o = argv[ai] + 1;
- done = 0;
- optarg = -1;
- while (*o && !done) {
- /* find matching option */
- if ((mi = optMatch(opt, o, 0)) < 0)
- optFatal(_("unrecognized option `-%c'\n"), *o);
-
- /* does this option take an argument? */
- optarg = -1;
- arg = NULL;
- if (optNeedsArgument(&opt[mi])) {
- /* option needs an argument. find it. */
- arg = o + 1;
- if (!*arg) {
- if ((optarg = ai + 1) == *argc)
- optFatal(_("option `%s' requires an argument\n"),
- optString(&opt[mi], 0));
- arg = argv[optarg];
- }
- done = 1;
- }
- /* perform the action of this option. */
- optExecute(&opt[mi], arg, 0);
- ++o;
- }
- /* remove option and any argument from the argv-array. */
- if (optarg >= 0)
- argvRemove(argc, argv, ai);
- argvRemove(argc, argv, ai);
- } else {
- /* a non-option argument */
- ++ai;
- }
- }
-}
diff --git a/hwclock/shhopt.h b/hwclock/shhopt.h
deleted file mode 100644
index ca8501ef5..000000000
--- a/hwclock/shhopt.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/* $Id: shhopt.h,v 2.2 1997/07/06 23:11:58 aebr Exp $ */
-#ifndef SHHOPT_H
-#define SHHOPT_H
-
-/* constants for recognized option types. */
-typedef enum {
- OPT_END, /* nothing. used as ending element. */
- OPT_FLAG, /* no argument following. sets variable to 1. */
- OPT_STRING, /* string argument. */
- OPT_INT, /* signed integer argument. */
- OPT_UINT, /* unsigned integer argument. */
- OPT_LONG, /* signed long integer argument. */
- OPT_ULONG, /* unsigned long integer argument. */
-} optArgType;
-
-/* flags modifying the default way options are handeled. */
-#define OPT_CALLFUNC 1 /* pass argument to a function. */
-
-typedef struct {
- char shortName; /* Short option name. */
- char *longName; /* Long option name, no including '--'. */
- optArgType type; /* Option type. */
- void *arg; /* Pointer to variable to fill with argument,
- * or pointer to function if Type == OPT_FUNC. */
- int flags; /* Modifier flags. */
-} optStruct;
-
-
-void optSetFatalFunc(void (*f)(const char *, ...));
-void optParseOptions(int *argc, char *argv[],
- const optStruct opt[], int allowNegNum);
-
-#endif