#undef USE_ICONV
#include <stdio.h>
#if defined __GLIBC__ && __GLIBC__ >= 2 && defined USE_ICONV
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <locale.h>
#include <langinfo.h>
#include <iconv.h>
#include "man-iconv.h"
#include "util.h"
#include "man.h"
static char *
find_iconv(void) {
static char *iconv_path = NULL;
static int inited = 0;
if (!inited) {
char *file = getenv("MAN_ICONV_PATH");
if (!file)
file = "/usr/bin/iconv";
if (access(file, X_OK) == 0)
iconv_path = my_strdup(file);
inited = 1;
}
return iconv_path;
}
static char *
iconv_extra_flags(void) {
static char *iconv_flags = "-cs";
static int inited = 0;
if (!inited) {
char *opt = getenv("MAN_ICONV_OPT");
if (opt)
iconv_flags = my_strdup(opt);
inited = 1;
}
return iconv_flags;
}
static char *
get_locale_charset (void) {
char *old_lc_ctype, *charset;
if ((charset = getenv("MAN_ICONV_OUTPUT_CHARSET")) == NULL) {
old_lc_ctype = setlocale(LC_CTYPE, "");
charset = nl_langinfo(CODESET);
setlocale(LC_CTYPE, old_lc_ctype);
}
return charset;
}
static char *
get_man_charset (const char *path) {
char *charset_env, *file, *path2, *p;
FILE *f = NULL;
charset_env = getenv("MAN_ICONV_INPUT_CHARSET");
if (charset_env)
return charset_env;
if (!path || !*path)
return NULL;
if (debug)
fprintf(stderr, "get_man_charset: path=%s\n", path);
path2 = my_strdup(path);
p = strrchr(path2, '/');
if (p && !strcmp(p, "/..")) {
*p = 0;
file = my_xsprintf("%s/.charset", path2);
f = fopen(file, "r");
free(file);
}
free(path2);
if (f == NULL) {
file = my_xsprintf("%s/.charset", path);
f = fopen(file, "r");
free(file);
}
if (f) {
char charset[100], *p;
fgets(charset, sizeof(charset), f);
fclose(f);
fprintf(stderr, "read %s\n", charset);
p = strchr(charset, '\n');
if (p) {
*p = 0;
return my_strdup(charset);
}
}
return NULL;
}
static int
is_conversion_supported (char *from, char *to) {
iconv_t cd;
if (!from || !*from || !to || !*to || !strcmp(from,to))
return 0;
if ((cd = iconv_open(to, from)) != (iconv_t) -1) {
iconv_close(cd);
return 1;
}
return 0;
}
const char *
get_converter (const char *path) {
char *from, *to, *iconv_path;
iconv_path = find_iconv();
from = get_man_charset(path);
to = get_locale_charset();
if (debug)
fprintf(stderr, "get_converter: iconv_path=%s from=%s to=%s\n",
iconv_path, from, to);
if (iconv_path && is_conversion_supported(from, to))
return my_xsprintf("%s %s -f %s -t %s",
iconv_path, iconv_extra_flags(), from, to);
return NULL;
}
#else
#include "man-iconv.h"
const char *
get_converter (const char *path) {
return NULL;
}
#endif