summaryrefslogtreecommitdiffstats
path: root/src/lib/krb5
diff options
context:
space:
mode:
authorRichard Basch <probe@mit.edu>1995-12-05 03:24:44 +0000
committerRichard Basch <probe@mit.edu>1995-12-05 03:24:44 +0000
commitebce7ef5ab8cfd20536458d7511806bfe157677f (patch)
tree780d0d281cf518cda58f27876080e287d75c0ccf /src/lib/krb5
parented76d309de0d2971519888997e7584104f1896fb (diff)
Moved most string-type conversion routines from libkadm to libkrb5 to
reduce the dependencies on libkadm and for better support of multiple encryption type lookup in krb5.conf. git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@7159 dc483132-0cff-0310-8789-dd5450dbe970
Diffstat (limited to 'src/lib/krb5')
-rw-r--r--src/lib/krb5/krb/Makefile.in2
-rw-r--r--src/lib/krb5/krb/str_conv.c668
2 files changed, 670 insertions, 0 deletions
diff --git a/src/lib/krb5/krb/Makefile.in b/src/lib/krb5/krb/Makefile.in
index 27e7fac96..2d1c7978e 100644
--- a/src/lib/krb5/krb/Makefile.in
+++ b/src/lib/krb5/krb/Makefile.in
@@ -75,6 +75,7 @@ OBJS= addr_comp.$(OBJEXT) \
ser_princ.$(OBJEXT) \
serialize.$(OBJEXT) \
srv_rcache.$(OBJEXT) \
+ str_conv.$(OBJEXT) \
tgtname.$(OBJEXT) \
unparse.$(OBJEXT) \
walk_rtree.$(OBJEXT)
@@ -147,6 +148,7 @@ SRCS= $(srcdir)/addr_comp.c \
$(srcdir)/ser_princ.c \
$(srcdir)/serialize.c \
$(srcdir)/srv_rcache.c \
+ $(srcdir)/str_conv.c \
$(srcdir)/tgtname.c \
$(srcdir)/unparse.c \
$(srcdir)/walk_rtree.c
diff --git a/src/lib/krb5/krb/str_conv.c b/src/lib/krb5/krb/str_conv.c
new file mode 100644
index 000000000..4190b03da
--- /dev/null
+++ b/src/lib/krb5/krb/str_conv.c
@@ -0,0 +1,668 @@
+/*
+ * lib/kadm/str_conv.c
+ *
+ * Copyright 1995 by the Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in 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.
+ *
+ */
+
+/*
+ * str_conv.c - Convert between strings and Kerberos internal data.
+ */
+
+/*
+ * Table of contents:
+ *
+ * String decoding:
+ * ----------------
+ * krb5_string_to_enctype() - Convert string to krb5_enctype.
+ * krb5_string_to_salttype() - Convert string to salttype (krb5_int32)
+ * krb5_string_to_cksumtype() - Convert string to krb5_cksumtype;
+ * krb5_string_to_timestamp() - Convert string to krb5_timestamp.
+ * krb5_string_to_deltat() - Convert string to krb5_deltat.
+ *
+ * String encoding:
+ * ----------------
+ * krb5_enctype_to_string() - Convert krb5_enctype to string.
+ * krb5_salttype_to_string() - Convert salttype (krb5_int32) to string.
+ * krb5_cksumtype_to_string() - Convert krb5_cksumtype to string.
+ * krb5_timestamp_to_string() - Convert krb5_timestamp to string.
+ * krb5_timestamp_to_sfstring() - Convert krb5_timestamp to short filled string
+ * krb5_deltat_to_string() - Convert krb5_deltat to string.
+ */
+
+#include "k5-int.h"
+
+/*
+ * Local data structures.
+ */
+struct enctype_lookup_entry {
+ krb5_enctype ktt_enctype; /* Keytype */
+ const char * ktt_specifier; /* How to recognize it */
+ const char * ktt_output; /* How to spit it out */
+};
+
+struct salttype_lookup_entry {
+ krb5_int32 stt_enctype; /* Salt type */
+ const char * stt_specifier; /* How to recognize it */
+ const char * stt_output; /* How to spit it out */
+};
+
+struct cksumtype_lookup_entry {
+ krb5_cksumtype cst_cksumtype; /* Checksum type */
+ const char * cst_specifier; /* How to recognize it */
+ const char * cst_output; /* How to spit it out */
+};
+
+struct deltat_match_entry {
+ const char * dt_scan_format; /* sscanf format */
+ int dt_nmatch; /* Number to match */
+ int dt_dindex; /* Day index */
+ int dt_hindex; /* Hour index */
+ int dt_mindex; /* Minute index */
+ int dt_sindex; /* Second index */
+};
+
+/*
+ * Local strings
+ */
+
+/* Keytype strings */
+static const char enctype_des_in[] = "des";
+static const char enctype_null_in[] = "null";
+static const char enctype_descbccrc_in[] = "des-cbc-crc";
+static const char enctype_descbcmd4_in[] = "des-cbc-md4";
+static const char enctype_descbcmd5_in[] = "des-cbc-md5";
+static const char enctype_des3cbcmd5_in[] = "des3-cbc-md5";
+static const char enctype_descbcraw_in[] = "des-cbc-raw";
+static const char enctype_null_out[] = "Null";
+static const char enctype_descbccrc_out[] = "DES cbc mode with CRC-32";
+static const char enctype_descbcmd4_out[] = "DES cbc mode with RSA-MD4";
+static const char enctype_descbcmd5_out[] = "DES cbc mode with RSA-MD5";
+static const char enctype_des3cbcmd5_out[] = "Triple DES cbc mode with RSA-MD5";
+static const char enctype_descbcraw_out[] = "DES cbc mode raw";
+
+/* Salttype strings */
+static const char stype_v5_in[] = "normal";
+static const char stype_v4_in[] = "v4";
+static const char stype_norealm_in[] = "norealm";
+static const char stype_olrealm_in[] = "onlyrealm";
+static const char stype_special_in[] = "special";
+static const char stype_v5_out[] = "Version 5";
+static const char stype_v4_out[] = "Version 4";
+static const char stype_norealm_out[] = "Version 5 - No Realm";
+static const char stype_olrealm_out[] = "Version 5 - Realm Only";
+static const char stype_special_out[] = "Special";
+
+/* Checksum type strings */
+static const char cstype_crc32_in[] = "crc32";
+static const char cstype_md4_in[] = "md4";
+static const char cstype_md4des_in[] = "md4-des";
+static const char cstype_descbc_in[] = "des-cbc";
+static const char cstype_md5_in[] = "md5";
+static const char cstype_md5des_in[] = "md5-des";
+static const char cstype_crc32_out[] = "CRC-32";
+static const char cstype_md4_out[] = "RSA-MD4";
+static const char cstype_md4des_out[] = "RSA-MD4 with DES cbc mode";
+static const char cstype_descbc_out[] = "DES cbc mode";
+static const char cstype_md5_out[] = "RSA-MD5";
+static const char cstype_md5des_out[] = "RSA-MD5 with DES cbc mode";
+
+/* Absolute time strings */
+static const char atime_full_digits[] = "%y%m%d%H%M%S";
+static const char atime_full_digits_d[] = "%y.%m.%d.%H.%M.%S";
+static const char atime_nsec_digits[] = "%y%m%d%H%M";
+static const char atime_rel_hms[] = "%H%M%S";
+static const char atime_rel_hm[] = "%H%M";
+static const char atime_rel_col_hms[] = "%T";
+static const char atime_rel_col_hm[] = "%R";
+static const char atime_ldep_sfmt[] = "%x:%X";
+static const char atime_full_text[] = "%d-%b-%Y:%T";
+static const char atime_full_text_nos[] = "%d-%b-%Y:%R";
+#if !HAVE_STRPTIME
+static const char ascan_full_digits[] = "%02d%02d%02d%02d%02d%02d";
+static const char ascan_full_digits_d[] = "%02d.%02d.%02d.%02d.%02d.%02d";
+static const char ascan_nsec_digits[] = "%02d%02d%02d%02d%02d";
+static const char ascan_rel_hms[] = "%02d%02d%02d";
+static const char ascan_rel_hm[] = "%02d%02d";
+static const char ascan_rel_col_hms[] = "%02d:%02d:%02d";
+static const char ascan_rel_col_hm[] = "%02d:%02d";
+#endif /* !HAVE_STRPTIME */
+#ifdef HAVE_STRFTIME
+static const char sftime_ldep_time[] = "%c";
+static const char sftime_med_fmt[] = "%d %b %y %T";
+static const char sftime_short_fmt[] = "%x %X";
+static const char sftime_last_fmt[] = "%d/%m/%y %R";
+#endif /* HAVE_STRFTIME */
+static const char sftime_default_fmt[] = "%02d/%02d/%02d %02d:%02d";
+static const size_t sftime_default_len = 2+1+2+1+2+1+2+1+2+1;
+
+/* Delta time strings */
+static const char dtscan_dhms_notext[] = "%d-%02d:%02d:%02d";
+static const char dtscan_dhms_stext[] = "%dd%dh%dm%ds";
+static const char dtscan_hms_notext[] = "%d:%02d:%02d";
+static const char dtscan_hms_stext[] = "%dh%dm%ds";
+static const char dtscan_hm_notext[] = "%d:%02d";
+static const char dtscan_hm_stext[] = "%dh%dm";
+static const char dtscan_days[] = "%d%[d]";
+static const char dtscan_hours[] = "%d%[h]";
+static const char dtscan_minutes[] = "%d%[m]";
+static const char dtscan_seconds[] = "%d%[s]";
+static const char dt_day_singular[] = "day";
+static const char dt_day_plural[] = "days";
+static const char dt_output_donly[] = "%d %s";
+static const char dt_output_dhms[] = "%d %s %02d:%02d:%02d";
+static const char dt_output_hms[] = "%d:%02d:%02d";
+
+/*
+ * Lookup tables.
+ */
+
+static const struct enctype_lookup_entry enctype_table[] = {
+/* krb5_enctype input specifier output string */
+/*------------- ----------------------- ------------------------*/
+{ ENCTYPE_NULL, enctype_null_in, enctype_null_out },
+{ ENCTYPE_DES_CBC_MD5, enctype_des_in, enctype_descbcmd5_out },
+{ ENCTYPE_DES_CBC_CRC, enctype_descbccrc_in, enctype_descbccrc_out },
+{ ENCTYPE_DES_CBC_MD4, enctype_descbcmd4_in, enctype_descbcmd4_out },
+{ ENCTYPE_DES_CBC_MD5, enctype_descbcmd5_in, enctype_descbcmd5_out },
+{ ENCTYPE_DES3_CBC_MD5, enctype_des3cbcmd5_in, enctype_des3cbcmd5_out },
+{ ENCTYPE_DES_CBC_RAW, enctype_descbcraw_in, enctype_descbcraw_out }
+};
+static const int enctype_table_nents = sizeof(enctype_table)/
+ sizeof(enctype_table[0]);
+
+static const struct salttype_lookup_entry salttype_table[] = {
+/* salt type input specifier output string */
+/*----------------------------- ----------------------- ------------------*/
+{ KRB5_KDB_SALTTYPE_NORMAL, stype_v5_in, stype_v5_out },
+{ KRB5_KDB_SALTTYPE_V4, stype_v4_in, stype_v4_out },
+{ KRB5_KDB_SALTTYPE_NOREALM, stype_norealm_in, stype_norealm_out },
+{ KRB5_KDB_SALTTYPE_ONLYREALM, stype_olrealm_in, stype_olrealm_out },
+{ KRB5_KDB_SALTTYPE_SPECIAL, stype_special_in, stype_special_out }
+};
+static const int salttype_table_nents = sizeof(salttype_table)/
+ sizeof(salttype_table[0]);
+
+static const struct cksumtype_lookup_entry cksumtype_table[] = {
+/* krb5_cksumtype input specifier output string */
+/*----------------------- --------------------- ------------------------*/
+{ CKSUMTYPE_CRC32, cstype_crc32_in, cstype_crc32_out },
+{ CKSUMTYPE_RSA_MD4, cstype_md4_in, cstype_md4_out },
+{ CKSUMTYPE_RSA_MD4_DES, cstype_md4des_in, cstype_md4des_out },
+{ CKSUMTYPE_DESCBC, cstype_descbc_in, cstype_descbc_out },
+{ CKSUMTYPE_RSA_MD5, cstype_md5_in, cstype_md5_out },
+{ CKSUMTYPE_RSA_MD5_DES, cstype_md5des_in, cstype_md5des_out }
+};
+static const int cksumtype_table_nents = sizeof(cksumtype_table)/
+ sizeof(cksumtype_table[0]);
+
+static const char * const atime_format_table[] = {
+atime_full_digits, /* yymmddhhmmss */
+atime_full_digits_d, /* yy.mm.dd.hh.mm.ss */
+atime_nsec_digits, /* yymmddhhmm */
+atime_rel_hms, /* hhmmss */
+atime_rel_hm, /* hhmm */
+atime_rel_col_hms, /* hh:mm:ss */
+atime_rel_col_hm, /* hh:mm */
+/* The following not really supported unless native strptime present */
+atime_ldep_sfmt, /*locale-dependent short format */
+atime_full_text, /* dd-month-yyyy:hh:mm:ss */
+atime_full_text_nos /* dd-month-yyyy:hh:mm */
+};
+static const int atime_format_table_nents = sizeof(atime_format_table)/
+ sizeof(atime_format_table[0]);
+
+#ifdef HAVE_STRFTIME
+static const char * const sftime_format_table[] = {
+sftime_ldep_time, /* Default locale-dependent date and time */
+sftime_med_fmt, /* dd mon yy hh:mm:ss */
+sftime_short_fmt, /* locale-dependent short format */
+sftime_last_fmt /* dd/mm/yy hh:mm */
+};
+static const int sftime_format_table_nents = sizeof(sftime_format_table)/
+ sizeof(sftime_format_table[0]);
+#endif /* HAVE_STRFTIME */
+
+static const struct deltat_match_entry deltat_table[] = {
+/* scan format nmatch daypos hourpos minpos secpos */
+/*--------------------- ------- ------- ------- ------- --------*/
+{ dtscan_dhms_notext, 4, 0, 1, 2, 3 },
+{ dtscan_dhms_stext, 4, 0, 1, 2, 3 },
+{ dtscan_hms_notext, 3, -1, 0, 1, 2 },
+{ dtscan_hms_stext, 3, -1, 0, 1, 2 },
+{ dtscan_hm_notext, 2, -1, -1, 0, 1 },
+{ dtscan_hm_stext, 2, -1, -1, 0, 1 },
+{ dtscan_days, 2, 0, -1, -1, -1 },
+{ dtscan_hours, 2, -1, 0, -1, -1 },
+{ dtscan_minutes, 2, -1, -1, 0, -1 },
+{ dtscan_seconds, 2, -1, -1, -1, 0 }
+};
+static const int deltat_table_nents = sizeof(deltat_table)/
+ sizeof(deltat_table[0]);
+
+#if !HAVE_STRPTIME
+/*
+ * Rudimentary version of strptime for systems which don't have it.
+ */
+static char *
+strptime(buf, format, tm)
+ char *buf;
+ const char *format;
+ struct tm *tm;
+{
+ int year, month, day, hour, minute, second;
+ char *bp;
+ time_t now;
+
+ /*
+ * We only understand the following fixed formats:
+ * %y%m%d%H%M%S
+ * %y.%m.%d.%H.%M.%S
+ * %y%m%d%H%M
+ * %H%M%S
+ * %H%M
+ * %T
+ * %R
+ */
+ bp = (char *) NULL;
+ if (!strcmp(format, atime_full_digits) &&
+ (sscanf(buf, ascan_full_digits,
+ &year, &month, &day, &hour, &minute, &second) == 6)) {
+ tm->tm_year = year;
+ tm->tm_mon = month - 1;
+ tm->tm_mday = day;
+ tm->tm_hour = hour;
+ tm->tm_min = minute;
+ tm->tm_sec = second;
+ bp = &buf[strlen(atime_full_digits)];
+ }
+ else if (!strcmp(format,atime_full_digits_d) &&
+ (sscanf(buf, ascan_full_digits_d,
+ &year, &month, &day, &hour, &minute, &second) == 6)) {
+ tm->tm_year = year;
+ tm->tm_mon = month - 1;
+ tm->tm_mday = day;
+ tm->tm_hour = hour;
+ tm->tm_min = minute;
+ tm->tm_sec = second;
+ bp = &buf[strlen(atime_full_digits_d)];
+ }
+ else if (!strcmp(format, atime_nsec_digits) &&
+ (sscanf(buf, ascan_nsec_digits,
+ &year, &month, &day, &hour, &minute) == 5)) {
+ tm->tm_year = year;
+ tm->tm_mon = month - 1;
+ tm->tm_mday = day;
+ tm->tm_hour = hour;
+ tm->tm_min = minute;
+ tm->tm_sec = 0;
+ bp = &buf[strlen(atime_nsec_digits)];
+ }
+ else if (!strcmp(format, atime_rel_hms) &&
+ (sscanf(buf, ascan_rel_hms, &hour, &minute, &second) == 3)) {
+ now = time((time_t *) NULL);
+ memcpy(tm, localtime(&now), sizeof(struct tm));
+ tm->tm_hour = hour;
+ tm->tm_min = minute;
+ tm->tm_sec = second;
+ bp = &buf[strlen(atime_rel_hms)];
+ }
+ else if (!strcmp(format, atime_rel_hm) &&
+ (sscanf(buf, ascan_rel_hm, &hour, &minute) == 2)) {
+ now = time((time_t *) NULL);
+ memcpy(tm, localtime(&now), sizeof(struct tm));
+ tm->tm_hour = hour;
+ tm->tm_min = minute;
+ bp = &buf[strlen(atime_rel_hm)];
+ }
+ else if (!strcmp(format, atime_rel_col_hms) &&
+ (sscanf(buf, ascan_rel_col_hms, &hour, &minute, &second) == 3)) {
+ now = time((time_t *) NULL);
+ memcpy(tm, localtime(&now), sizeof(struct tm));
+ tm->tm_hour = hour;
+ tm->tm_min = minute;
+ tm->tm_sec = second;
+ bp = &buf[strlen(atime_rel_col_hms)];
+ }
+ else if (!strcmp(format, atime_rel_col_hm) &&
+ (sscanf(buf, ascan_rel_col_hm, &hour, &minute) == 2)) {
+ now = time((time_t *) NULL);
+ memcpy(tm, localtime(&now), sizeof(struct tm));
+ tm->tm_hour = hour;
+ tm->tm_min = minute;
+ bp = &buf[strlen(atime_rel_col_hm)];
+ }
+ return(bp);
+}
+#endif /* HAVE_STRPTIME */
+
+/*
+ * String to internal datatype routines.
+ *
+ * These routines return 0 for success, EINVAL for invalid entry.
+ */
+krb5_error_code
+krb5_string_to_enctype(string, enctypep)
+ char * string;
+ krb5_enctype * enctypep;
+{
+ int i;
+ int found;
+
+ found = 0;
+ for (i=0; i<enctype_table_nents; i++) {
+ if (!strcasecmp(string, enctype_table[i].ktt_specifier)) {
+ found = 1;
+ *enctypep = enctype_table[i].ktt_enctype;
+ break;
+ }
+ }
+ return((found) ? 0 : EINVAL);
+}
+
+krb5_error_code
+krb5_string_to_salttype(string, salttypep)
+ char * string;
+ krb5_int32 * salttypep;
+{
+ int i;
+ int found;
+
+ found = 0;
+ for (i=0; i<salttype_table_nents; i++) {
+ if (!strcasecmp(string, salttype_table[i].stt_specifier)) {
+ found = 1;
+ *salttypep = salttype_table[i].stt_enctype;
+ break;
+ }
+ }
+ return((found) ? 0 : EINVAL);
+}
+
+krb5_error_code
+krb5_string_to_cksumtype(string, cksumtypep)
+ char * string;
+ krb5_cksumtype * cksumtypep;
+{
+ int i;
+ int found;
+
+ found = 0;
+ for (i=0; i<cksumtype_table_nents; i++) {
+ if (!strcasecmp(string, cksumtype_table[i].cst_specifier)) {
+ found = 1;
+ *cksumtypep = cksumtype_table[i].cst_cksumtype;
+ break;
+ }
+ }
+ return((found) ? 0 : EINVAL);
+}
+
+krb5_error_code
+krb5_string_to_timestamp(string, timestampp)
+ char * string;
+ krb5_timestamp * timestampp;
+{
+ int i;
+ int found;
+ struct tm timebuf;
+
+ found = 0;
+ memset(&timebuf, 0, sizeof(timebuf));
+ for (i=0; i<atime_format_table_nents; i++) {
+ if (strptime(string, atime_format_table[i], &timebuf)) {
+ found = 1;
+ break;
+ }
+ }
+ if (found)
+ *timestampp = (krb5_timestamp) mktime(&timebuf);
+ return((found) ? 0 : EINVAL);
+}
+
+krb5_error_code
+krb5_string_to_deltat(string, deltatp)
+ char * string;
+ krb5_deltat * deltatp;
+{
+ int i;
+ int found;
+ int svalues[4];
+ int days, hours, minutes, seconds;
+ krb5_deltat dt;
+
+ found = 0;
+ days = hours = minutes = seconds = 0;
+ for (i=0; i<deltat_table_nents; i++) {
+ if (sscanf(string, deltat_table[i].dt_scan_format,
+ &svalues[0], &svalues[1], &svalues[2], &svalues[3]) ==
+ deltat_table[i].dt_nmatch) {
+ if (deltat_table[i].dt_dindex >= 0)
+ days = svalues[deltat_table[i].dt_dindex];
+ if (deltat_table[i].dt_hindex >= 0)
+ hours = svalues[deltat_table[i].dt_hindex];
+ if (deltat_table[i].dt_mindex >= 0)
+ minutes = svalues[deltat_table[i].dt_mindex];
+ if (deltat_table[i].dt_sindex >= 0)
+ seconds = svalues[deltat_table[i].dt_sindex];
+ found = 1;
+ break;
+ }
+ }
+ if (found) {
+ dt = days;
+ dt *= 24;
+ dt += hours;
+ dt *= 60;
+ dt += minutes;
+ dt *= 60;
+ dt += seconds;
+ *deltatp = dt;
+ }
+ return((found) ? 0 : EINVAL);
+}
+
+/*
+ * Internal datatype to string routines.
+ *
+ * These routines return 0 for success, EINVAL for invalid parameter, ENOMEM
+ * if the supplied buffer/length will not contain the output.
+ */
+krb5_error_code
+krb5_enctype_to_string(enctype, buffer, buflen)
+ krb5_enctype enctype;
+ char * buffer;
+ size_t buflen;
+{
+ int i;
+ const char *out;
+
+ out = (char *) NULL;
+ for (i=0; i<enctype_table_nents; i++) {
+ if (enctype == enctype_table[i].ktt_enctype) {
+ out = enctype_table[i].ktt_output;
+ break;
+ }
+ }
+ if (out) {
+ if (buflen > strlen(out))
+ strcpy(buffer, out);
+ else
+ out = (char *) NULL;
+ return((out) ? 0 : ENOMEM);
+ }
+ else
+ return(EINVAL);
+}
+
+krb5_error_code
+krb5_salttype_to_string(salttype, buffer, buflen)
+ krb5_int32 salttype;
+ char * buffer;
+ size_t buflen;
+{
+ int i;
+ const char *out;
+
+ out = (char *) NULL;
+ for (i=0; i<salttype_table_nents; i++) {
+ if (salttype == salttype_table[i].stt_enctype) {
+ out = salttype_table[i].stt_output;
+ break;
+ }
+ }
+ if (out) {
+ if (buflen > strlen(out))
+ strcpy(buffer, out);
+ else
+ out = (char *) NULL;
+ return((out) ? 0 : ENOMEM);
+ }
+ else
+ return(EINVAL);
+}
+
+krb5_error_code
+krb5_cksumtype_to_string(cksumtype, buffer, buflen)
+ krb5_cksumtype cksumtype;
+ char * buffer;
+ size_t buflen;
+{
+ int i;
+ const char *out;
+
+ out = (char *) NULL;
+ for (i=0; i<cksumtype_table_nents; i++) {
+ if (cksumtype == cksumtype_table[i].cst_cksumtype) {
+ out = cksumtype_table[i].cst_output;
+ break;
+ }
+ }
+ if (out) {
+ if (buflen > strlen(out))
+ strcpy(buffer, out);
+ else
+ out = (char *) NULL;
+ return((out) ? 0 : ENOMEM);
+ }
+ else
+ return(EINVAL);
+}
+
+krb5_error_code
+krb5_timestamp_to_string(timestamp, buffer, buflen)
+ krb5_timestamp timestamp;
+ char * buffer;
+ size_t buflen;
+{
+#if HAVE_STRFTIME
+ if (strftime(buffer, buflen, "%c", localtime((time_t *) &timestamp)))
+ return(0);
+ else
+ return(ENOMEM);
+#else /* HAVE_STRFTIME */
+ if (strlen(ctime((time_t *) &timestamp)) <= buflen) {
+ strcpy(buffer, ctime((time_t *) &timestamp));
+ /* ctime returns <datestring>\n\0 */
+ buffer[strlen(buffer)-1] = '\0';
+ return(0);
+ }
+#endif /* HAVE_STRFTIME */
+ return(ENOMEM);
+}
+
+krb5_error_code
+krb5_timestamp_to_sfstring(timestamp, buffer, buflen, pad)
+ krb5_timestamp timestamp;
+ char * buffer;
+ size_t buflen;
+ char * pad;
+{
+ struct tm *tmp;
+ size_t i;
+ size_t ndone;
+
+ tmp = localtime((time_t *) &timestamp);
+ ndone = 0;
+#if HAVE_STRFTIME
+ for (i=0; i<sftime_format_table_nents; i++) {
+ if ((ndone = strftime(buffer, buflen, sftime_format_table[i], tmp)))
+ break;
+ }
+#endif /* HAVE_STRFTIME */
+ if (!ndone) {
+ if (buflen >= sftime_default_len) {
+ sprintf(buffer, sftime_default_fmt,
+ tmp->tm_mday, tmp->tm_mon+1, tmp->tm_year,
+ tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+ ndone = strlen(buffer);
+ }
+ }
+ if (ndone && pad) {
+ for (i=ndone; i<buflen-1; i++)
+ buffer[i] = *pad;
+ buffer[buflen-1] = '\0';
+ }
+ return((ndone) ? 0 : ENOMEM);
+}
+
+krb5_error_code
+krb5_deltat_to_string(deltat, buffer, buflen)
+ krb5_deltat deltat;
+ char * buffer;
+ size_t buflen;
+{
+ int days, hours, minutes, seconds;
+ krb5_deltat dt;
+ krb5_error_code retval;
+
+ days = (int) (deltat / (24*3600l));
+ dt = deltat % (24*3600l);
+ hours = (int) (dt / 3600);
+ dt %= 3600;
+ minutes = (int) (dt / 60);
+ seconds = (int) (dt % 60);
+
+ retval = 0;
+ if (days) {
+ if (hours || minutes || seconds) {
+ if (buflen < (strlen(dt_output_dhms)+strlen(dt_day_plural)))
+ retval = ENOMEM;
+ else
+ sprintf(buffer, dt_output_dhms, days,
+ (days > 1) ? dt_day_plural : dt_day_singular,
+ hours, minutes, seconds);
+ }
+ else {
+ if (buflen < (strlen(dt_output_donly)+strlen(dt_day_plural)))
+ retval = ENOMEM;
+ else
+ sprintf(buffer, dt_output_donly, days,
+ (days > 1) ? dt_day_plural : dt_day_singular);
+ }
+ }
+ else {
+ if (buflen < strlen(dt_output_hms))
+ retval = ENOMEM;
+ else
+ sprintf(buffer, dt_output_hms, hours, minutes, seconds);
+ }
+ return(retval);
+}