Blob Blame History Raw
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);
 }