summaryrefslogtreecommitdiffstats
path: root/usr.sbin/tzsetup
diff options
context:
space:
mode:
authorwollman <wollman@FreeBSD.org>1995-04-24 21:04:35 +0000
committerwollman <wollman@FreeBSD.org>1995-04-24 21:04:35 +0000
commita90da0ca41b1694b5b2cf38b7c36f912ad28b19e (patch)
tree980263aed3bcc058801d9292608a3f1b083db5eb /usr.sbin/tzsetup
parentb75b8fba1b9063ee1f4f26a3c5e5d25503c71650 (diff)
downloadFreeBSD-src-a90da0ca41b1694b5b2cf38b7c36f912ad28b19e.zip
FreeBSD-src-a90da0ca41b1694b5b2cf38b7c36f912ad28b19e.tar.gz
Grand new all-singing, dialog-wielding tzsetup(8). Still needs a man page.
Diffstat (limited to 'usr.sbin/tzsetup')
-rw-r--r--usr.sbin/tzsetup/Makefile20
-rw-r--r--usr.sbin/tzsetup/grok.pl76
-rw-r--r--usr.sbin/tzsetup/main.c265
-rw-r--r--usr.sbin/tzsetup/tzmenu.c178
-rw-r--r--usr.sbin/tzsetup/tzsetup.h55
5 files changed, 588 insertions, 6 deletions
diff --git a/usr.sbin/tzsetup/Makefile b/usr.sbin/tzsetup/Makefile
index 6959dcb..0e316ef 100644
--- a/usr.sbin/tzsetup/Makefile
+++ b/usr.sbin/tzsetup/Makefile
@@ -1,12 +1,20 @@
-# $Id$
+# $Id: Makefile,v 1.1 1994/09/13 23:01:57 wollman Exp $
-NOPROG= tzsetup
+PROG= tzsetup
NOMAN=
+SRCS= main.c tzmenu.c menus.c
+CFLAGS+= -I. -I${.CURDIR}
+CLEANFILES+= menus.c
+LDADD+= -ldialog -lncurses -lmytinfo
+DPADD+= ${LIBDIALOG} ${LIBNCURSES} ${LIBMYTINFO}
-all depend:
+Z= ${.CURDIR}/../../share/zoneinfo
+.PATH: ${Z}
-beforeinstall:
- $(INSTALL) -c -m $(BINMODE) -o $(BINOWN) -g $(BINGRP) \
- ${.CURDIR}/tzsetup.sh ${DESTDIR}${BINDIR}/tzsetup
+ZF= africa antarctica asia australasia europe northamerica southamerica
+
+menus.c: grok.pl ${ZF}
+ perl ${.CURDIR}/grok.pl `for a in ${ZF}; do echo ${Z}/$$a; done` \
+ > ${.TARGET}
.include <bsd.prog.mk>
diff --git a/usr.sbin/tzsetup/grok.pl b/usr.sbin/tzsetup/grok.pl
new file mode 100644
index 0000000..434554f
--- /dev/null
+++ b/usr.sbin/tzsetup/grok.pl
@@ -0,0 +1,76 @@
+# -*- Perl -*-
+
+%reg_ctry = ();
+%ctry_files = ();
+%file_descrs = ();
+
+while(<>) {
+ next if(!/^\# ZONE-DESCR/);
+ chop;
+ split;
+
+ shift(@_); shift(@_); # get rid of # ZONE-DESCR
+
+ # Now $_[0] is region, $_[1] is filename, $_[2] is country,
+ # and @_[3 .. $#_] is the description
+ $reg = $_[0];
+ $file = $_[1];
+ $ctry = $_[2];
+ $descr = join(' ', @_[3 .. $#_]);
+
+ if($reg_ctry{$reg} =~ /$ctry/) {
+ # do nothing
+ } else {
+ $reg_ctry{$reg} = $ctry . "," . $reg_ctry{$reg};
+ }
+
+ $ctry_files{$ctry} .= ",$reg/$file";
+ $file_descrs{"$reg/$file"} = $descr;
+}
+
+print "/* This file automatically generated. */\n";
+print "#include \"tzsetup.h\"\n";
+
+foreach $ctry (sort keys %ctry_files) {
+ print "const char *files_$ctry\[\] = {\n";
+ $ctry_files{$ctry} =~ s/^,//;
+ foreach $file (sort {$file_descrs{$a} cmp $file_descrs{$b}}
+ split(/,/, $ctry_files{$ctry})) {
+ print "\t\"$file\",\n";
+ }
+ print "\t0 };\n";
+ print "const char *menu_$ctry\[\] = {\n";
+ $i = 0;
+
+ foreach $file (sort {$file_descrs{$a} cmp $file_descrs{$b}}
+ split(/,/, $ctry_files{$ctry})) {
+ $i++;
+ print "\t\"$i\", \"$file_descrs{$file}\",\n";
+ }
+ print "\t0, 0 };\n";
+
+ print "struct country $ctry = { files_$ctry, menu_$ctry, $i };\n";
+}
+
+foreach $reg (sort keys %reg_ctry) {
+ print "\nstruct country *menu_$reg\[\] = {\n";
+ $reg_ctry{$reg} =~ s/,$//;
+ foreach $ctry (sort split(/,/, $reg_ctry{$reg})) {
+ print "\t&$ctry,\n";
+ }
+
+ print "\t0 };\n";
+ print "const char *name_$reg\[\] = {\n";
+ $i = 0;
+ foreach $ctry (sort split(/,/, $reg_ctry{$reg})) {
+ $i++;
+ $ctry =~ s/_/ /g;
+ print "\t\"$i\", \"$ctry\",\n";
+ }
+ print "\t0, 0 };\n";
+
+ print "struct region $reg = { menu_$reg, name_$reg, $i };\n";
+}
+
+exit 0;
+
diff --git a/usr.sbin/tzsetup/main.c b/usr.sbin/tzsetup/main.c
new file mode 100644
index 0000000..bfdd1e1
--- /dev/null
+++ b/usr.sbin/tzsetup/main.c
@@ -0,0 +1,265 @@
+/*
+ * Copyright 1995 Massachusetts Institute of Technology
+ *
+ * Permission to use, copy, modify, and distribute this software and
+ * its documentation for any purpose and without fee is hereby
+ * granted, provided that both the above copyright notice and this
+ * permission notice appear in all copies, that both the above
+ * copyright notice and this permission notice appear in all
+ * supporting documentation, and that the name of M.I.T. not be used
+ * in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission. M.I.T. makes
+ * no representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied
+ * warranty.
+ *
+ * THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''. M.I.T. DISCLAIMS
+ * ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT
+ * SHALL M.I.T. 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.
+ */
+
+static const char rcsid[] =
+ "$Id$";
+
+#include <stdio.h>
+#include <ncurses.h>
+#include <dialog.h>
+#include <limits.h>
+#include <time.h>
+#include <stdlib.h>
+#include <errno.h>
+
+#include "tzsetup.h"
+
+#define PATH_LOCALTIME "/etc/localtime"
+#define PATH_WALL_CMOS_CLOCK "/etc/wall_cmos_clock"
+#define PATH_ZONEINFO "/usr/share/zoneinfo"
+
+static int set_time();
+
+enum cmos { CMOS_UTC, CMOS_LOCAL, CMOS_LEAVE } cmos_state = CMOS_LEAVE;
+static int time_adjust = 0;
+static enum cmos cmos(enum cmos);
+static void fiddle_cmos(void);
+
+int
+main(void)
+{
+ const char *tz;
+
+ init_dialog();
+ if (set_time() != 0) {
+ end_dialog();
+ exit(1);
+ }
+
+ tz = tzmenu();
+
+ fiddle_cmos();
+
+ dialog_notify("Reboot the machine for changes to take effect.\n");
+ end_dialog();
+
+ fprintf(stderr,
+ "Now reboot your computer for the changes to take effect.\n");
+ return tz ? 0 : 1;
+}
+
+static int
+set_time(void)
+{
+ unsigned char result[_POSIX2_LINE_MAX];
+ unsigned char buf2[_POSIX2_LINE_MAX];
+ static struct tm usertm, systm;
+ time_t usertime, systime;
+ long diff;
+ int rv;
+
+ /*
+ * If /etc/wall_cmos_clock exists, or if there is already a timezone
+ * file installed, then just leave it alone and don't ask the user
+ * what time it is (because the system clock is already in POSIX
+ * time so we don't need to adjust anything later on).
+ */
+ time(&systime);
+ systm = *localtime(&systime);
+ if (systm.tm_zone[0]
+ || access(PATH_WALL_CMOS_CLOCK, 0) == 0) {
+ cmos_state = CMOS_LEAVE;
+ return 0;
+ }
+
+ usertm = systm;
+ usertm.tm_isdst = -1;
+
+ result[0] = '\0';
+
+ while(1) {
+ rv = dialog_inputbox("Checking current time",
+ "Please enter the current local time"
+ " using 24-hour style,\n"
+ "in the form HH:MM",
+ 8, 78, result);
+ if (rv != 0)
+ return 1;
+
+ if (result[0]) {
+ if (sscanf(result, "%d:%d:%d", &usertm.tm_hour,
+ &usertm.tm_min,
+ &usertm.tm_sec) < 2) {
+ snprintf(buf2, sizeof buf2,
+ "Invalid time format: %s", result);
+ dialog_notify(buf2);
+ continue;
+ }
+ usertime = mktime(&usertm);
+ if (usertime == (time_t)-1) {
+ snprintf(buf2, sizeof buf2,
+ "Unreasonable time: %s", result);
+ dialog_notify(buf2);
+ continue;
+ }
+
+ diff = usertime - systime;
+ if (labs(diff) > 15*60) {
+ cmos_state = cmos(CMOS_LOCAL);
+ if (diff > 0) {
+ time_adjust = ((diff + 15*60)/30*60
+ * 30*60);
+ } else {
+ time_adjust = ((diff - 15*60)/30*60
+ * 30*60);
+ }
+ } else {
+ cmos_state = cmos(CMOS_UTC);
+ time_adjust = 0;
+ }
+ break;
+ }
+ }
+ return 0;
+}
+
+static unsigned char *cmos_list[] = {
+ "1", "CMOS clock is set to local time",
+ "2", "CMOS clock is set to Universal time (UTC)",
+ "3", "I'm not sure, leave it alone"
+};
+
+static enum cmos
+cmos(enum cmos state)
+{
+ int rv, sel = 0;
+ unsigned char buf[_POSIX2_LINE_MAX];
+ unsigned char result[_POSIX2_LINE_MAX];
+
+ snprintf(buf, sizeof buf, "%s seems most likely",
+ state == CMOS_UTC ? "UTC" : "local time");
+
+ rv = dialog_menu("CMOS clock in local time or UTC",
+ buf, 12, 78, 3, 3, cmos_list, result, &sel, 0);
+ if (rv == 0) {
+ return sel;
+ } else {
+ return state;
+ }
+}
+
+static void
+fiddle_cmos(void)
+{
+ FILE *fp;
+
+ switch(cmos_state) {
+ case CMOS_LEAVE:
+ case CMOS_UTC:
+ break;
+ case CMOS_LOCAL:
+ fp = fopen(PATH_WALL_CMOS_CLOCK, "w");
+ if(fp) {
+ fclose(fp);
+ } /* xxx should have error message */
+ }
+}
+
+
+int
+setzone(const char *zone)
+{
+ time_t systime;
+ struct tm *tm;
+ char msg[_POSIX2_LINE_MAX];
+ int rv;
+ FILE *ifp, *ofp;
+
+ snprintf(msg, sizeof msg, "TZ=%s", zone);
+ putenv(msg);
+ tzset();
+ time(&systime);
+ systime += time_adjust;
+ tm = localtime(&systime);
+
+ snprintf(msg, sizeof msg,
+ "Does %02d:%02d:%02d %d.%d.%04d %s look reasonable?",
+ tm->tm_hour, tm->tm_min, tm->tm_sec, tm->tm_mday, tm->tm_mon,
+ tm->tm_year + 1900, tm->tm_zone);
+
+ rv = dialog_yesno("Verifying timezone selection",
+ msg, -1, -1);
+ if (rv)
+ return 1;
+
+ snprintf(msg, sizeof msg, PATH_ZONEINFO "/%s", zone);
+ ifp = fopen(msg, "r");
+ if (!ifp) {
+ snprintf(msg, sizeof msg,
+ "Could not open " PATH_ZONEINFO "/%s: %s",
+ zone, strerror(errno));
+ dialog_notify(msg);
+ return 1;
+ }
+
+ ofp = fopen(PATH_LOCALTIME, "w");
+ if (!ofp) {
+ snprintf(msg, sizeof msg, "Could not open " PATH_LOCALTIME
+ ": %s", strerror(errno));
+ dialog_notify(msg);
+ fclose(ifp);
+ return 1;
+ }
+
+ while((rv = fread(msg, 1, sizeof msg, ifp)) > 0) {
+ int rv2;
+ if((rv2 = fwrite(msg, 1, rv, ofp)) != rv) {
+ snprintf(msg, sizeof msg,
+ "Could not write " PATH_LOCALTIME ": %s",
+ strerror(errno));
+out:
+ dialog_notify(msg);
+ fclose(ifp);
+ fclose(ofp);
+ unlink(PATH_LOCALTIME);
+ return 1;
+ }
+ }
+ if (rv < 0) {
+ snprintf(msg, sizeof msg, "Could not read timezone file: %s",
+ strerror(errno));
+ goto out;
+ }
+
+ fclose(ifp);
+ fclose(ofp);
+ snprintf(msg, sizeof msg, "Installed timezone file %s", zone);
+ dialog_notify(msg);
+ return 0;
+}
diff --git a/usr.sbin/tzsetup/tzmenu.c b/usr.sbin/tzsetup/tzmenu.c
new file mode 100644
index 0000000..c27c417
--- /dev/null
+++ b/usr.sbin/tzsetup/tzmenu.c
@@ -0,0 +1,178 @@
+/*
+ * Copyright 1995 Massachusetts Institute of Technology
+ *
+ * Permission to use, copy, modify, and distribute this software and
+ * its documentation for any purpose and without fee is hereby
+ * granted, provided that both the above copyright notice and this
+ * permission notice appear in all copies, that both the above
+ * copyright notice and this permission notice appear in all
+ * supporting documentation, and that the name of M.I.T. not be used
+ * in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission. M.I.T. makes
+ * no representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied
+ * warranty.
+ *
+ * THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''. M.I.T. DISCLAIMS
+ * ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT
+ * SHALL M.I.T. 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.
+ */
+
+static const char rcsid[] =
+ "$Id$";
+
+#include <stdio.h>
+#include <ncurses.h>
+#include <dialog.h>
+#include <limits.h>
+
+#include "tzsetup.h"
+
+static const char *regmenu[] = {
+ "1", "Africa",
+ "2", "Asia",
+ "3", "Atlantic Ocean islands",
+ "4", "Australia",
+ "5", "Europe (including Russia)",
+ "6", "Indian Ocean islands",
+ "7", "North and South America",
+ "8", "Pacific Ocean islands"
+};
+
+static struct region *regions[] = {
+ &Africa,
+ &Asia,
+ &Atlantic,
+ &Australia,
+ &Europe,
+ &Indian,
+ &America,
+ &Pacific
+};
+
+#define NREGIONS 8
+
+static const char *country_menu(const struct region *, const char *);
+
+const char *
+tzmenu(void)
+{
+ unsigned char rbuf[_POSIX2_LINE_MAX];
+ int rv;
+ int item = 0;
+ int sc = 0;
+ const char *res;
+
+ while(1) {
+ dialog_clear();
+ rv = dialog_menu("Timezone Selector",
+ "Select a region",
+ NREGIONS + 6,
+ 78,
+ NREGIONS,
+ NREGIONS,
+ (unsigned char **)regmenu,
+ rbuf,
+ &item,
+ &sc);
+
+
+ if (rv != 0) {
+ return 0;
+ }
+
+ res = country_menu(regions[item],
+ regmenu[2 * item + 1]);
+
+ if (res)
+ return res;
+ }
+}
+
+static const char *location_menu(const struct country *, const char *);
+
+static const char *
+country_menu(const struct region *reg, const char *name)
+{
+ unsigned char rbuf[_POSIX2_LINE_MAX];
+ unsigned char title[_POSIX2_LINE_MAX];
+ int rv;
+ int item = 0;
+ int sc = 0;
+ const char *res;
+
+ snprintf(title, sizeof title, "Timezone Selector - %s", name);
+
+ while(1) {
+ dialog_clear();
+ rv = dialog_menu(title, "Select a country",
+ reg->r_count > 18 ? 24 : reg->r_count + 6,
+ 78,
+ reg->r_count > 18 ? 18 : reg->r_count,
+ reg->r_count,
+ (unsigned char **)reg->r_menu,
+ rbuf,
+ &item,
+ &sc);
+
+
+ if (rv != 0) {
+ return 0;
+ }
+
+ sscanf(rbuf, "%d", &rv);
+
+ res = location_menu(reg->r_ctrylist[rv - 1],
+ reg->r_menu[2 * (rv - 1) + 1]);
+
+ if (res)
+ return res;
+ }
+}
+
+static const char *
+location_menu(const struct country *ctry, const char *name)
+{
+ unsigned char rbuf[_POSIX2_LINE_MAX];
+ unsigned char title[_POSIX2_LINE_MAX];
+ int rv;
+ int item = 0;
+ int sc = 0;
+ const char *res;
+
+ snprintf(title, sizeof title, "Timezone Selector - %s", name);
+
+ while(1) {
+ dialog_clear();
+ rv = dialog_menu(title, "Select a location",
+ ctry->c_count + 6,
+ 78,
+ ctry->c_count,
+ ctry->c_count,
+ (unsigned char **)ctry->c_menu,
+ rbuf,
+ &item,
+ &sc);
+
+
+ if (rv != 0) {
+ return 0;
+ }
+
+
+ rv = setzone(ctry->c_filelist[item]);
+
+ if (rv == 0)
+ return ctry->c_filelist[item];
+ }
+}
+
diff --git a/usr.sbin/tzsetup/tzsetup.h b/usr.sbin/tzsetup/tzsetup.h
new file mode 100644
index 0000000..ab8731b
--- /dev/null
+++ b/usr.sbin/tzsetup/tzsetup.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright 1995 Massachusetts Institute of Technology
+ *
+ * Permission to use, copy, modify, and distribute this software and
+ * its documentation for any purpose and without fee is hereby
+ * granted, provided that both the above copyright notice and this
+ * permission notice appear in all copies, that both the above
+ * copyright notice and this permission notice appear in all
+ * supporting documentation, and that the name of M.I.T. not be used
+ * in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission. M.I.T. makes
+ * no representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied
+ * warranty.
+ *
+ * THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''. M.I.T. DISCLAIMS
+ * ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT
+ * SHALL M.I.T. 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.
+ *
+ * $Id$
+ */
+
+struct country {
+ const char **c_filelist;
+ const char **c_menu;
+ int c_count;
+};
+
+struct region {
+ struct country **r_ctrylist;
+ const char **r_menu;
+ int r_count;
+};
+
+extern struct region Africa; /* all of Africa */
+extern struct region America; /* North and South America */
+extern struct region Asia; /* all of Asia */
+extern struct region Atlantic; /* Atlantic Ocean islands */
+extern struct region Australia; /* Australia */
+extern struct region Europe; /* all of Europe including Russia */
+extern struct region Indian; /* Indian Ocean islands */
+extern struct region Pacific; /* Pacific Ocean islands */
+
+extern int setzone(const char *);
+extern const char *tzmenu(void);
+
OpenPOWER on IntegriCloud