summaryrefslogtreecommitdiffstats
path: root/eBones/usr.sbin/kdb_edit
diff options
context:
space:
mode:
authorcsgr <csgr@FreeBSD.org>1994-09-30 14:50:09 +0000
committercsgr <csgr@FreeBSD.org>1994-09-30 14:50:09 +0000
commit105186eeeeb6aa85d5ff5818e8abf65e3912cb7d (patch)
tree785c4a61d39a776700a06b092960ec07c3629dd6 /eBones/usr.sbin/kdb_edit
parentd011ad6fdacef9638bbc4bd1d25bae91e6f1515b (diff)
downloadFreeBSD-src-105186eeeeb6aa85d5ff5818e8abf65e3912cb7d.zip
FreeBSD-src-105186eeeeb6aa85d5ff5818e8abf65e3912cb7d.tar.gz
Initial import of eBones.
(Including all changes for FreeBSD - importing the original eBones distribution would be too complex at this stage, since I don't have access to Piero's CVS.) (If you want to include eBones in your system, don't forget to include MAKE_EBONES in /etc/make.conf.) (This stuff is now also suppable from braae.ru.ac.za.) Bones originally from MIT SIPB. Original port to FreeBSD 1.x by Piero Serini. Moved to FreeBSD 2.0 by Doug Rabson and Geoff Rehmet. Nice bug fixes from Doug Rabson.
Diffstat (limited to 'eBones/usr.sbin/kdb_edit')
-rw-r--r--eBones/usr.sbin/kdb_edit/Makefile12
-rw-r--r--eBones/usr.sbin/kdb_edit/kdb_edit.855
-rw-r--r--eBones/usr.sbin/kdb_edit/kdb_edit.c470
-rw-r--r--eBones/usr.sbin/kdb_edit/maketime.c83
-rw-r--r--eBones/usr.sbin/kdb_edit/time.h45
5 files changed, 665 insertions, 0 deletions
diff --git a/eBones/usr.sbin/kdb_edit/Makefile b/eBones/usr.sbin/kdb_edit/Makefile
new file mode 100644
index 0000000..65a5e5a
--- /dev/null
+++ b/eBones/usr.sbin/kdb_edit/Makefile
@@ -0,0 +1,12 @@
+# From: @(#)Makefile 5.2 (Berkeley) 2/14/91
+# $Id: Makefile,v 1.2 1994/07/19 19:23:53 g89r4222 Exp $
+
+PROG= kdb_edit
+CFLAGS+=-DKERBEROS -DDEBUG -I. -I${.CURDIR}/../include
+SRCS= kdb_edit.c maketime.c
+.PATH: ${.CURDIR}/../kdb_edit
+DPADD= ${LIBKDB} ${LIBKRB} ${LIBDES}
+LDADD= -L${KDBOBJDIR} -lkdb -L${KRBOBJDIR} -lkrb -L${DESOBJDIR} -ldes
+NOMAN= noman
+
+.include <bsd.prog.mk>
diff --git a/eBones/usr.sbin/kdb_edit/kdb_edit.8 b/eBones/usr.sbin/kdb_edit/kdb_edit.8
new file mode 100644
index 0000000..1cfd6ed
--- /dev/null
+++ b/eBones/usr.sbin/kdb_edit/kdb_edit.8
@@ -0,0 +1,55 @@
+.\" from: kdb_edit.8,v 4.1 89/01/23 11:08:55 jtkohl Exp $
+.\" $Id: kdb_edit.8,v 1.2 1994/07/19 19:27:27 g89r4222 Exp $
+.\" Copyright 1989 by the Massachusetts Institute of Technology.
+.\"
+.\" For copying and distribution information,
+.\" please see the file <Copyright.MIT>.
+.\"
+.TH KDB_EDIT 8 "Kerberos Version 4.0" "MIT Project Athena"
+.SH NAME
+kdb_edit \- Kerberos key distribution center database editing utility
+.SH SYNOPSIS
+kdb_edit [
+.B \-n
+]
+.SH DESCRIPTION
+.I kdb_edit
+is used to create or change principals stored in the Kerberos key
+distribution center (KDC) database.
+.PP
+When executed,
+.I kdb_edit
+prompts for the master key string and verifies that it matches the
+master key stored in the database.
+If the
+.B \-n
+option is specified, the master key is instead fetched from the master
+key cache file.
+.PP
+Once the master key has been verified,
+.I kdb_edit
+begins a prompt loop. The user is prompted for the principal and
+instance to be modified. If the entry is not found the user may create
+it.
+Once an entry is found or created, the user may set the password,
+expiration date, maximum ticket lifetime, and attributes.
+Default expiration dates, maximum ticket lifetimes, and attributes are
+presented in brackets; if the user presses return the default is selected.
+There is no default password.
+The password RANDOM is interpreted specially, and if entered
+the user may have the program select a random DES key for the
+principal.
+.PP
+Upon successfully creating or changing the entry, ``Edit O.K.'' is
+printed.
+.SH DIAGNOSTICS
+.TP 20n
+"verify_master_key: Invalid master key, does not match database."
+The master key string entered was incorrect.
+.SH FILES
+.TP 20n
+/kerberos/principal.pag, /kerberos/principal.dir
+DBM files containing database
+.TP
+/.k
+Master key cache file.
diff --git a/eBones/usr.sbin/kdb_edit/kdb_edit.c b/eBones/usr.sbin/kdb_edit/kdb_edit.c
new file mode 100644
index 0000000..4c02db6
--- /dev/null
+++ b/eBones/usr.sbin/kdb_edit/kdb_edit.c
@@ -0,0 +1,470 @@
+/*
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * This routine changes the Kerberos encryption keys for principals,
+ * i.e., users or services.
+ *
+ * from: kdb_edit.c,v 4.2 90/01/09 16:05:09 raeburn Exp $
+ * $Id: kdb_edit.c,v 1.3 1994/09/09 21:43:46 g89r4222 Exp $
+ */
+
+/*
+ * exit returns 0 ==> success -1 ==> error
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: kdb_edit.c,v 1.3 1994/09/09 21:43:46 g89r4222 Exp $";
+#endif lint
+
+#include <stdio.h>
+#include <signal.h>
+#include <errno.h>
+#include <strings.h>
+#include <sys/ioctl.h>
+#include <sys/file.h>
+#include "time.h"
+#include <des.h>
+#include <krb.h>
+#include <krb_db.h>
+/* MKEYFILE is now defined in kdc.h */
+#include <kdc.h>
+
+extern char *errmsg();
+extern int errno;
+extern char *strcpy();
+
+void sig_exit();
+
+#define zaptime(foo) bzero((char *)(foo), sizeof(*(foo)))
+
+char prog[32];
+char *progname = prog;
+int nflag = 0;
+int cflag;
+int lflag;
+int uflag;
+int debug;
+extern kerb_debug;
+
+Key_schedule KS;
+C_Block new_key;
+unsigned char *input;
+
+unsigned char *ivec;
+int i, j;
+int more;
+
+char *in_ptr;
+char input_name[ANAME_SZ];
+char input_instance[INST_SZ];
+char input_string[ANAME_SZ];
+
+#define MAX_PRINCIPAL 10
+Principal principal_data[MAX_PRINCIPAL];
+
+static Principal old_principal;
+static Principal default_princ;
+
+static C_Block master_key;
+static C_Block session_key;
+static Key_schedule master_key_schedule;
+static char pw_str[255];
+static long master_key_version;
+
+/*
+ * gets replacement
+ */
+static char * s_gets(char * str, int len)
+{
+ int i;
+ char *s;
+
+ if((s = fgets(str, len, stdin)) == NULL)
+ return(s);
+ if(str[i = (strlen(str)-1)] == '\n')
+ str[i] = '\0';
+ return(s);
+}
+
+main(argc, argv)
+ int argc;
+ char *argv[];
+
+{
+ /* Local Declarations */
+
+ long n;
+
+ prog[sizeof prog - 1] = '\0'; /* make sure terminated */
+ strncpy(prog, argv[0], sizeof prog - 1); /* salt away invoking
+ * program */
+
+ /* Assume a long is four bytes */
+ if (sizeof(long) != 4) {
+ fprintf(stdout, "%s: size of long is %d.\n", sizeof(long), prog);
+ exit(-1);
+ }
+ /* Assume <=32 signals */
+ if (NSIG > 32) {
+ fprintf(stderr, "%s: more than 32 signals defined.\n", prog);
+ exit(-1);
+ }
+ while (--argc > 0 && (*++argv)[0] == '-')
+ for (i = 1; argv[0][i] != '\0'; i++) {
+ switch (argv[0][i]) {
+
+ /* debug flag */
+ case 'd':
+ debug = 1;
+ continue;
+
+ /* debug flag */
+ case 'l':
+ kerb_debug |= 1;
+ continue;
+
+ case 'n': /* read MKEYFILE for master key */
+ nflag = 1;
+ continue;
+
+ default:
+ fprintf(stderr, "%s: illegal flag \"%c\"\n",
+ progname, argv[0][i]);
+ Usage(); /* Give message and die */
+ }
+ };
+
+ fprintf(stdout, "Opening database...\n");
+ fflush(stdout);
+ kerb_init();
+ if (argc > 0) {
+ if (kerb_db_set_name(*argv) != 0) {
+ fprintf(stderr, "Could not open altername database name\n");
+ exit(1);
+ }
+ }
+
+#ifdef notdef
+ no_core_dumps(); /* diddle signals to avoid core dumps! */
+
+ /* ignore whatever is reasonable */
+ signal(SIGHUP, SIG_IGN);
+ signal(SIGINT, SIG_IGN);
+ signal(SIGTSTP, SIG_IGN);
+
+#endif
+
+ if (kdb_get_master_key ((nflag == 0),
+ master_key, master_key_schedule) != 0) {
+ fprintf (stdout, "Couldn't read master key.\n");
+ fflush (stdout);
+ exit (-1);
+ }
+
+ if ((master_key_version = kdb_verify_master_key(master_key,
+ master_key_schedule,
+ stdout)) < 0)
+ exit (-1);
+
+ /* lookup the default values */
+ n = kerb_get_principal(KERB_DEFAULT_NAME, KERB_DEFAULT_INST,
+ &default_princ, 1, &more);
+ if (n != 1) {
+ fprintf(stderr,
+ "%s: Kerberos error on default value lookup, %d found.\n",
+ progname, n);
+ exit(-1);
+ }
+ fprintf(stdout, "Previous or default values are in [brackets] ,\n");
+ fprintf(stdout, "enter return to leave the same, or new value.\n");
+
+ while (change_principal()) {
+ }
+
+ cleanup();
+}
+
+change_principal()
+{
+ static char temp[255];
+ int creating = 0;
+ int editpw = 0;
+ int changed = 0;
+ long temp_long;
+ int n;
+ struct tm *tp, edate, *localtime();
+ long maketime();
+
+ fprintf(stdout, "\nPrincipal name: ");
+ fflush(stdout);
+ if (!s_gets(input_name, ANAME_SZ-1) || *input_name == '\0')
+ return 0;
+ fprintf(stdout, "Instance: ");
+ fflush(stdout);
+ /* instance can be null */
+ s_gets(input_instance, INST_SZ-1);
+ j = kerb_get_principal(input_name, input_instance, principal_data,
+ MAX_PRINCIPAL, &more);
+ if (!j) {
+ fprintf(stdout, "\n\07\07<Not found>, Create [y] ? ");
+ s_gets(temp, sizeof(temp)-1); /* Default case should work, it didn't */
+ if (temp[0] != 'y' && temp[0] != 'Y' && temp[0] != '\0')
+ return -1;
+ /* make a new principal, fill in defaults */
+ j = 1;
+ creating = 1;
+ strcpy(principal_data[0].name, input_name);
+ strcpy(principal_data[0].instance, input_instance);
+ principal_data[0].old = NULL;
+ principal_data[0].exp_date = default_princ.exp_date;
+ principal_data[0].max_life = default_princ.max_life;
+ principal_data[0].attributes = default_princ.attributes;
+ principal_data[0].kdc_key_ver = (unsigned char) master_key_version;
+ principal_data[0].key_version = 0; /* bumped up later */
+ }
+ tp = localtime(&principal_data[0].exp_date);
+ (void) sprintf(principal_data[0].exp_date_txt, "%4d-%02d-%02d",
+ tp->tm_year > 1900 ? tp->tm_year : tp->tm_year + 1900,
+ tp->tm_mon + 1, tp->tm_mday); /* January is 0, not 1 */
+ for (i = 0; i < j; i++) {
+ for (;;) {
+ fprintf(stdout,
+ "\nPrincipal: %s, Instance: %s, kdc_key_ver: %d",
+ principal_data[i].name, principal_data[i].instance,
+ principal_data[i].kdc_key_ver);
+ editpw = 1;
+ changed = 0;
+ if (!creating) {
+ /*
+ * copy the existing data so we can use the old values
+ * for the qualifier clause of the replace
+ */
+ principal_data[i].old = (char *) &old_principal;
+ bcopy(&principal_data[i], &old_principal,
+ sizeof(old_principal));
+ printf("\nChange password [n] ? ");
+ s_gets(temp, sizeof(temp)-1);
+ if (strcmp("y", temp) && strcmp("Y", temp))
+ editpw = 0;
+ }
+ /* password */
+ if (editpw) {
+#ifdef NOENCRYPTION
+ placebo_read_pw_string(pw_str, sizeof pw_str,
+ "\nNew Password: ", TRUE);
+#else
+ des_read_pw_string(pw_str, sizeof pw_str,
+ "\nNew Password: ", TRUE);
+#endif
+ if (!strcmp(pw_str, "RANDOM")) {
+ printf("\nRandom password [y] ? ");
+ s_gets(temp, sizeof(temp)-1);
+ if (!strcmp("n", temp) || !strcmp("N", temp)) {
+ /* no, use literal */
+#ifdef NOENCRYPTION
+ bzero(new_key, sizeof(C_Block));
+ new_key[0] = 127;
+#else
+ string_to_key(pw_str, new_key);
+#endif
+ bzero(pw_str, sizeof pw_str); /* "RANDOM" */
+ } else {
+#ifdef NOENCRYPTION
+ bzero(new_key, sizeof(C_Block));
+ new_key[0] = 127;
+#else
+ random_key(new_key);
+#endif
+ bzero(pw_str, sizeof pw_str);
+ }
+ } else if (!strcmp(pw_str, "NULL")) {
+ printf("\nNull Key [y] ? ");
+ s_gets(temp, sizeof(temp)-1);
+ if (!strcmp("n", temp) || !strcmp("N", temp)) {
+ /* no, use literal */
+#ifdef NOENCRYPTION
+ bzero(new_key, sizeof(C_Block));
+ new_key[0] = 127;
+#else
+ string_to_key(pw_str, new_key);
+#endif
+ bzero(pw_str, sizeof pw_str); /* "NULL" */
+ } else {
+
+ principal_data[i].key_low = 0;
+ principal_data[i].key_high = 0;
+ goto null_key;
+ }
+ } else {
+#ifdef NOENCRYPTION
+ bzero(new_key, sizeof(C_Block));
+ new_key[0] = 127;
+#else
+ string_to_key(pw_str,new_key);
+#endif
+ bzero(pw_str, sizeof pw_str);
+ }
+
+ /* seal it under the kerberos master key */
+ kdb_encrypt_key (new_key, new_key,
+ master_key, master_key_schedule,
+ ENCRYPT);
+ bcopy(new_key, &principal_data[i].key_low, 4);
+ bcopy(((long *) new_key) + 1,
+ &principal_data[i].key_high, 4);
+ bzero(new_key, sizeof(new_key));
+ null_key:
+ /* set master key version */
+ principal_data[i].kdc_key_ver =
+ (unsigned char) master_key_version;
+ /* bump key version # */
+ principal_data[i].key_version++;
+ fprintf(stdout,
+ "\nPrincipal's new key version = %d\n",
+ principal_data[i].key_version);
+ fflush(stdout);
+ changed = 1;
+ }
+ /* expiration date */
+ fprintf(stdout, "Expiration date (enter yyyy-mm-dd) [ %s ] ? ",
+ principal_data[i].exp_date_txt);
+ zaptime(&edate);
+ while (s_gets(temp, sizeof(temp)-1) && ((n = strlen(temp)) >
+ sizeof(principal_data[0].exp_date_txt))) {
+ bad_date:
+ fprintf(stdout, "\07\07Date Invalid\n");
+ fprintf(stdout,
+ "Expiration date (enter yyyy-mm-dd) [ %s ] ? ",
+ principal_data[i].exp_date_txt);
+ zaptime(&edate);
+ }
+
+ if (*temp) {
+ if (sscanf(temp, "%d-%d-%d", &edate.tm_year,
+ &edate.tm_mon, &edate.tm_mday) != 3)
+ goto bad_date;
+ (void) strcpy(principal_data[i].exp_date_txt, temp);
+ edate.tm_mon--; /* January is 0, not 1 */
+ edate.tm_hour = 23; /* nearly midnight at the end of the */
+ edate.tm_min = 59; /* specified day */
+ if (!(principal_data[i].exp_date = maketime(&edate, 1)))
+ goto bad_date;
+ changed = 1;
+ }
+
+ /* maximum lifetime */
+ fprintf(stdout, "Max ticket lifetime (*5 minutes) [ %d ] ? ",
+ principal_data[i].max_life);
+ while (s_gets(temp, sizeof(temp)-1) && *temp) {
+ if (sscanf(temp, "%d", &temp_long) != 1)
+ goto bad_life;
+ if (temp_long > 255 || (temp_long < 0)) {
+ bad_life:
+ fprintf(stdout, "\07\07Invalid, choose 0-255\n");
+ fprintf(stdout,
+ "Max ticket lifetime (*5 minutes) [ %d ] ? ",
+ principal_data[i].max_life);
+ continue;
+ }
+ changed = 1;
+ /* dont clobber */
+ principal_data[i].max_life = (unsigned short) temp_long;
+ break;
+ }
+
+ /* attributes */
+ fprintf(stdout, "Attributes [ %d ] ? ",
+ principal_data[i].attributes);
+ while (s_gets(temp, sizeof(temp)-1) && *temp) {
+ if (sscanf(temp, "%d", &temp_long) != 1)
+ goto bad_att;
+ if (temp_long > 65535 || (temp_long < 0)) {
+ bad_att:
+ fprintf(stdout, "\07\07Invalid, choose 0-65535\n");
+ fprintf(stdout, "Attributes [ %d ] ? ",
+ principal_data[i].attributes);
+ continue;
+ }
+ changed = 1;
+ /* dont clobber */
+ principal_data[i].attributes =
+ (unsigned short) temp_long;
+ break;
+ }
+
+ /*
+ * remaining fields -- key versions and mod info, should
+ * not be directly manipulated
+ */
+ if (changed) {
+ if (kerb_put_principal(&principal_data[i], 1)) {
+ fprintf(stdout,
+ "\nError updating Kerberos database");
+ } else {
+ fprintf(stdout, "Edit O.K.");
+ }
+ } else {
+ fprintf(stdout, "Unchanged");
+ }
+
+
+ bzero(&principal_data[i].key_low, 4);
+ bzero(&principal_data[i].key_high, 4);
+ fflush(stdout);
+ break;
+ }
+ }
+ if (more) {
+ fprintf(stdout, "\nThere were more tuples found ");
+ fprintf(stdout, "than there were space for");
+ }
+ return 1;
+}
+
+
+no_core_dumps()
+{
+
+ signal(SIGQUIT, sig_exit);
+ signal(SIGILL, sig_exit);
+ signal(SIGTRAP, sig_exit);
+ signal(SIGIOT, sig_exit);
+ signal(SIGEMT, sig_exit);
+ signal(SIGFPE, sig_exit);
+ signal(SIGBUS, sig_exit);
+ signal(SIGSEGV, sig_exit);
+ signal(SIGSYS, sig_exit);
+}
+
+void
+sig_exit(sig, code, scp)
+ int sig, code;
+ struct sigcontext *scp;
+{
+ cleanup();
+ fprintf(stderr,
+ "\nSignal caught, sig = %d code = %d old pc = 0x%X \nexiting",
+ sig, code, scp->sc_pc);
+ exit(-1);
+}
+
+
+cleanup()
+{
+
+ bzero(master_key, sizeof(master_key));
+ bzero(session_key, sizeof(session_key));
+ bzero(master_key_schedule, sizeof(master_key_schedule));
+ bzero(principal_data, sizeof(principal_data));
+ bzero(new_key, sizeof(new_key));
+ bzero(pw_str, sizeof(pw_str));
+}
+Usage()
+{
+ fprintf(stderr, "Usage: %s [-n]\n", progname);
+ exit(1);
+}
diff --git a/eBones/usr.sbin/kdb_edit/maketime.c b/eBones/usr.sbin/kdb_edit/maketime.c
new file mode 100644
index 0000000..057ecc3
--- /dev/null
+++ b/eBones/usr.sbin/kdb_edit/maketime.c
@@ -0,0 +1,83 @@
+/*
+ * Copyright 1990 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <Copyright.MIT>.
+ *
+ * Convert a struct tm * to a UNIX time.
+ *
+ * from: maketime.c,v 4.2 90/01/09 15:54:51 raeburn Exp $
+ * $Id: maketime.c,v 1.2 1994/07/19 19:23:56 g89r4222 Exp $
+ */
+
+#ifndef lint
+static char rcsid[] =
+"$Id: maketime.c,v 1.1 1994/03/21 16:23:54 piero Exp ";
+#endif lint
+
+#include <sys/time.h>
+
+#define daysinyear(y) (((y) % 4) ? 365 : (((y) % 100) ? 366 : (((y) % 400) ? 365 : 366)))
+
+#define SECSPERDAY 24*60*60
+#define SECSPERHOUR 60*60
+#define SECSPERMIN 60
+
+static int cumdays[] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334,
+ 365};
+
+static int leapyear[] = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
+static int nonleapyear[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
+
+long
+maketime(tp, local)
+register struct tm *tp;
+int local;
+{
+ register long retval;
+ int foo;
+ int *marray;
+
+ if (tp->tm_mon < 0 || tp->tm_mon > 11 ||
+ tp->tm_hour < 0 || tp->tm_hour > 23 ||
+ tp->tm_min < 0 || tp->tm_min > 59 ||
+ tp->tm_sec < 0 || tp->tm_sec > 59) /* out of range */
+ return 0;
+
+ retval = 0;
+ if (tp->tm_year < 1900)
+ foo = tp->tm_year + 1900;
+ else
+ foo = tp->tm_year;
+
+ if (foo < 1901 || foo > 2038) /* year is too small/large */
+ return 0;
+
+ if (daysinyear(foo) == 366) {
+ if (tp->tm_mon > 1)
+ retval+= SECSPERDAY; /* add leap day */
+ marray = leapyear;
+ } else
+ marray = nonleapyear;
+
+ if (tp->tm_mday < 0 || tp->tm_mday > marray[tp->tm_mon])
+ return 0; /* out of range */
+
+ while (--foo >= 1970)
+ retval += daysinyear(foo) * SECSPERDAY;
+
+ retval += cumdays[tp->tm_mon] * SECSPERDAY;
+ retval += (tp->tm_mday-1) * SECSPERDAY;
+ retval += tp->tm_hour * SECSPERHOUR + tp->tm_min * SECSPERMIN + tp->tm_sec;
+
+ if (local) {
+ /* need to use local time, so we retrieve timezone info */
+ struct timezone tz;
+ struct timeval tv;
+ if (gettimeofday(&tv, &tz) < 0) {
+ /* some error--give up? */
+ return(retval);
+ }
+ retval += tz.tz_minuteswest * SECSPERMIN;
+ }
+ return(retval);
+}
diff --git a/eBones/usr.sbin/kdb_edit/time.h b/eBones/usr.sbin/kdb_edit/time.h
new file mode 100644
index 0000000..ed128d8
--- /dev/null
+++ b/eBones/usr.sbin/kdb_edit/time.h
@@ -0,0 +1,45 @@
+/* Structure for use by time manipulating subroutines.
+ * The following library routines use it:
+ * libc: ctime, localtime, gmtime, asctime
+ * libcx: partime, maketime (may not be installed yet)
+ */
+
+/*
+ * from: time.h,v 1.1 82/05/06 11:34:29 wft Exp $
+ * $Id: time.h,v 1.2 1994/07/19 19:23:58 g89r4222 Exp $
+ */
+
+struct tm { /* See defines below for allowable ranges */
+ int tm_sec;
+ int tm_min;
+ int tm_hour;
+ int tm_mday;
+ int tm_mon;
+ int tm_year;
+ int tm_wday;
+ int tm_yday;
+ int tm_isdst;
+ int tm_zon; /* NEW: mins westward of Greenwich */
+ int tm_ampm; /* NEW: 1 if AM, 2 if PM */
+};
+
+#define LCLZONE (5*60) /* Until V7 ftime(2) works, this defines local zone*/
+#define TMNULL (-1) /* Items not specified are given this value
+ * in order to distinguish null specs from zero
+ * specs. This is only used by partime and
+ * maketime. */
+
+ /* Indices into TM structure */
+#define TM_SEC 0 /* 0-59 */
+#define TM_MIN 1 /* 0-59 */
+#define TM_HOUR 2 /* 0-23 */
+#define TM_MDAY 3 /* 1-31 day of month */
+#define TM_DAY TM_MDAY /* " synonym */
+#define TM_MON 4 /* 0-11 */
+#define TM_YEAR 5 /* (year-1900) (year) */
+#define TM_WDAY 6 /* 0-6 day of week (0 = Sunday) */
+#define TM_YDAY 7 /* 0-365 day of year */
+#define TM_ISDST 8 /* 0 Std, 1 DST */
+ /* New stuff */
+#define TM_ZON 9 /* 0-(24*60) minutes west of Greenwich */
+#define TM_AMPM 10 /* 1 AM, 2 PM */
OpenPOWER on IntegriCloud