summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--time/win32/timestr.c66
1 files changed, 65 insertions, 1 deletions
diff --git a/time/win32/timestr.c b/time/win32/timestr.c
index 7c70dec1c..b30440e4b 100644
--- a/time/win32/timestr.c
+++ b/time/win32/timestr.c
@@ -54,6 +54,7 @@
#include "win32/atime.h"
#include "apr_portable.h"
+#include "apr_strings.h"
APR_DECLARE_DATA const char apr_month_snames[12][4] =
{
@@ -154,6 +155,69 @@ APR_DECLARE(apr_status_t) apr_ctime(char *date_str, apr_time_t t)
return APR_SUCCESS;
}
+int win32_strftime_extra(char *s, size_t max, const char *format,
+ const struct tm *tm) {
+ /* If the new format string is bigger than max, the result string won't fit
+ * anyway. If format strings are added, made sure the padding below is
+ * enough */
+ char *new_format = (char *) malloc(max + 11);
+ size_t i, j, format_length = strlen(format);
+ int return_value;
+ int length_written;
+
+ for (i = 0, j = 0; (i < format_length && j < max);) {
+ if (format[i] != '%') {
+ new_format[j++] = format[i++];
+ continue;
+ }
+ switch (format[i+1]) {
+ case 'C':
+ length_written = apr_snprintf(new_format + j, max - j, "%2d",
+ (tm->tm_year + 1970)/100);
+ j = (length_written == -1) ? max : (j + length_written);
+ i += 2;
+ break;
+ case 'D':
+ /* Is this locale dependent? Shouldn't be...
+ Also note the year 2000 exposure here */
+ memcpy(new_format + j, "%m/%d/%y", 8);
+ i += 2;
+ j += 8;
+ break;
+ case 'r':
+ memcpy(new_format + j, "%I:%M:%S %p", 11);
+ i += 2;
+ j += 11;
+ break;
+ case 'T':
+ memcpy(new_format + j, "%H:%M:%S", 8);
+ i += 2;
+ j += 8;
+ break;
+ case 'e':
+ length_written = apr_snprintf(new_format + j, max - j, "%2d",
+ tm->tm_mday);
+ j = (length_written == -1) ? max : (j + length_written);
+ i += 2;
+ break;
+ default:
+ /* We know we can advance two characters forward here. Also
+ * makes sure that %% is preserved. */
+ new_format[j++] = format[i++];
+ new_format[j++] = format[i++];
+ }
+ }
+ if (j >= max) {
+ *s = '\0'; /* Defensive programming, okay since output is undefined*/
+ return_value = 0;
+ } else {
+ new_format[j] = '\0';
+ return_value = strftime(s, max, new_format, tm);
+ }
+ free(new_format);
+ return return_value;
+ }
+
APR_DECLARE(apr_status_t) apr_strftime(char *s, apr_size_t *retsize,
apr_size_t max, const char *format,
apr_exploded_time_t *xt)
@@ -169,6 +233,6 @@ APR_DECLARE(apr_status_t) apr_strftime(char *s, apr_size_t *retsize,
tm.tm_wday = xt->tm_wday;
tm.tm_yday = xt->tm_yday;
tm.tm_isdst = xt->tm_isdst;
- (*retsize) = strftime(s, max, format, &tm);
+ (*retsize) = win32_strftime_extra(s, max, format, &tm);
return APR_SUCCESS;
}