diff -urN calendar-1.25.orig/calendar.h calendar-1.25/calendar.h
--- calendar-1.25.orig/calendar.h 2009-03-03 22:37:55.000000000 -0500
+++ calendar-1.25/calendar.h 2009-03-04 00:08:53.000000000 -0500
@@ -31,6 +31,8 @@
#include <sys/uio.h>
+#include <iconv.h>
+
extern struct passwd *pw;
extern int doall;
extern int bodun_always;
@@ -70,6 +72,7 @@
int (*getev)(int);
};
+void convprint(FILE *, iconv_t, char *);
void cal(void);
void closecal(FILE *);
int getday(char *);
diff -urN calendar-1.25.orig/io.c calendar-1.25/io.c
--- calendar-1.25.orig/io.c 2009-03-03 22:37:55.000000000 -0500
+++ calendar-1.25/io.c 2009-03-04 00:11:21.000000000 -0500
@@ -61,10 +61,17 @@
#include <string.h>
#include <unistd.h>
+#include <langinfo.h>
+#include <iconv.h>
+
#include "pathnames.h"
#include "calendar.h"
+#define ICONV_TRANSLIT "/" "/" "TRANSLIT"
+#define ICONV_FROMCODE "UTF-8"
+#define ICONV_BUFSIZ (128)
+
struct iovec header[] = {
{ "From: ", 6 },
{ NULL, 0 },
@@ -76,6 +83,39 @@
{ "Auto-Submitted: auto-generated\n\n", 32 },
};
+void
+convprint(FILE *fp, iconv_t ic, char *inputbuf)
+{
+ char *iconv_input;
+ char *iconv_output;
+ char outputbuf[ICONV_BUFSIZ];
+ size_t inputsz;
+ size_t outputsz;
+ size_t iconv_result;
+
+ iconv_input = inputbuf;
+ inputsz = strlen(inputbuf);
+
+ while (inputsz > 0)
+ {
+ iconv_output = outputbuf;
+ outputsz = sizeof(outputbuf) - 1;
+
+ iconv_result = iconv(
+ ic,
+ &iconv_input,
+ &inputsz,
+ &iconv_output,
+ &outputsz
+ );
+ if ((((size_t) -1) == iconv_result) && (E2BIG != errno))
+ {
+ return;
+ }
+ outputbuf[sizeof(outputbuf) - outputsz - 1] = '\0';
+ (void)fprintf(fp, "%s", outputbuf);
+ }
+}
void
cal(void)
@@ -86,6 +126,42 @@
struct match *m;
FILE *fp;
+ char *langinfo_coding;
+ char *iconv_coding;
+ iconv_t ic;
+ int use_iconv;
+
+ use_iconv = 1;
+ iconv_coding = NULL;
+ ic = (iconv_t) -1;
+ (void)setlocale(LC_ALL, "");
+ langinfo_coding = nl_langinfo(CODESET);
+ if ((NULL == langinfo_coding) || ('\0' == *langinfo_coding))
+ {
+ use_iconv = 0;
+ }
+ else
+ {
+ iconv_coding = malloc(
+ strlen(langinfo_coding) + sizeof(ICONV_TRANSLIT)
+ );
+ }
+
+ if (NULL == iconv_coding)
+ {
+ use_iconv = 0;
+ }
+ else
+ {
+ sprintf(iconv_coding, "%s%s", langinfo_coding, ICONV_TRANSLIT);
+ ic = iconv_open(iconv_coding, ICONV_FROMCODE);
+ }
+
+ if (((iconv_t) -1) == ic)
+ {
+ use_iconv = 0;
+ }
+
events = NULL;
cur_evt = NULL;
if ((fp = opencal()) == NULL)
@@ -101,6 +177,14 @@
if (buf[0] == '\0')
continue;
if (strncmp(buf, "LANG=", 5) == 0) {
+ if (use_iconv)
+ {
+ char *coding_start = strchr(buf, '.');
+ if (NULL != coding_start)
+ {
+ strcpy(coding_start, ".UTF-8");
+ }
+ }
(void) setlocale(LC_ALL, buf + 5);
setnnames();
if (!strcmp(buf + 5, "ru_RU.KOI8-R") ||
@@ -215,8 +299,17 @@
}
tmp = events;
while (tmp) {
+ if (use_iconv)
+ {
+ convprint(fp, ic, tmp->print_date);
+ convprint(fp, ic, *(tmp->desc));
+ (void)fputc((int) '\n', fp);
+ }
+ else
+ {
(void)fprintf(fp, "%s%s\n", tmp->print_date, *(tmp->desc));
- tmp = tmp->next;
+ }
+ tmp = tmp->next;
}
tmp = events;
while (tmp) {
@@ -226,6 +319,17 @@
tmp = tmp->next;
free(events);
}
+
+ if (NULL != iconv_coding)
+ {
+ free(iconv_coding);
+ }
+
+ if (((iconv_t) -1) != ic)
+ {
+ iconv_close(ic);
+ }
+
closecal(fp);
}