#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <nl_types.h>
extern char *index (const char *, int);
extern char *my_malloc(int);
#ifndef DEFAULT_NLSPATH
# if __GLIBC__ >= 2
# define DEFAULT_NLSPATH "/usr/share/locale/%L/%N"
# else
# define DEFAULT_NLSPATH "/usr/lib/locale/%N/%L"
# endif
#endif
static nl_catd my_catopenpath(char *name, char *path);
static
nl_catd
my_catopen(char *name, int oflag) {
nl_catd fd;
fd = catopen(name, oflag);
if (fd == (nl_catd) -1 && oflag) {
oflag = 0;
fd = catopen(name, oflag);
}
if (fd == (nl_catd) -1) {
char *nlspath;
if (oflag)
return fd;
if (index(name, '/')) {
#ifdef __GLIBC__
return fd;
#else
return open(name, O_RDONLY);
#endif
}
nlspath = getenv("NLSPATH");
if (nlspath)
fd = my_catopenpath(name, nlspath);
if (fd == (nl_catd) -1)
fd = my_catopenpath(name, DEFAULT_NLSPATH);
}
return fd;
}
static nl_catd
my_catopenpath(char *name, char *nlspath) {
int fd;
nl_catd cfd = (nl_catd) -1;
char *path0, *path, *s, *file, *lang, *lang_l, *lang_t, *lang_c;
int langsz, namesz, sz, lang_l_sz, lang_t_sz, lang_c_sz;
namesz = strlen(name);
lang = getenv("LANG");
if (!lang)
lang = "";
langsz = strlen(lang);
lang_l = lang;
s = index(lang_l, '_');
if (!s) {
lang_t = lang_c = "";
lang_l_sz = langsz;
lang_t_sz = lang_c_sz = 0;
} else {
lang_l_sz = s - lang_l;
lang_t = s+1;
s = index(lang_t, '.');
if (!s) {
lang_c = "";
lang_t_sz = langsz - lang_l_sz - 1;
lang_c_sz = 0;
} else {
lang_t_sz = s - lang_t;
lang_c = s+1;
lang_c_sz = langsz - lang_l_sz - lang_t_sz - 2;
}
}
sz = 0;
s = nlspath;
while(*s) {
if(*s == '%') {
s++;
switch(*s) {
case '%':
sz++; break;
case 'N':
sz += namesz; break;
case 'L':
sz += langsz; break;
case 'l':
sz += lang_l_sz; break;
case 't':
sz += lang_t_sz; break;
case 'c':
sz += lang_c_sz; break;
default:
break;
}
} else if (*s == ':' && (s == nlspath || s[-1] == ':')) {
sz += (namesz + 1);
} else
sz++;
s++;
}
path0 = my_malloc(sz + 1);
path = path0;
s = nlspath;
while(*s) {
if(*s == '%') {
s++;
switch(*s) {
case '%':
*path++ = '%'; break;
case 'N':
strncpy(path, name, namesz); path += namesz; break;
case 'L':
strncpy(path, lang, langsz); path += langsz; break;
case 'l':
strncpy(path, lang_l, lang_l_sz); path += lang_l_sz; break;
case 't':
strncpy(path, lang_t, lang_t_sz); path += lang_t_sz; break;
case 'c':
strncpy(path, lang_c, lang_c_sz); path += lang_c_sz; break;
default:
break;
}
} else if (*s == ':' && (s == nlspath || s[-1] == ':')) {
strncpy(path, name, namesz); path += namesz;
*path++ = ':';
} else
*path++ = *s;
s++;
}
*path = 0;
path = path0;
while(path) {
file = path;
s = index(path, ':');
if (s) {
*s = 0;
path = s+1;
} else
path = 0;
fd = open(file, O_RDONLY);
if (fd != -1) {
close(fd);
cfd = catopen(file, 0);
break;
}
}
free(path0);
return cfd;
}