#include "lint.h"
#include "file64.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <stdio.h>
#include "libc.h"
#include "ldpart.h"
#include "setlocale.h"
static int split_lines(char *, const char *);
int
__part_load_locale(const char *name,
char **locale_buf, const char *category_filename,
int locale_buf_size_max, int locale_buf_size_min,
const char **dst_localebuf)
{
int saverr, fd, i, num_lines;
char *lbuf, *p;
const char *plim;
char filename[PATH_MAX];
struct stat st;
size_t namesize, bufsize;
namesize = strlen(name) + 1;
(void) snprintf(filename, sizeof (filename), "%s/%s/%s/LCL_DATA",
_PathLocale, name, category_filename);
if ((fd = open(filename, O_RDONLY)) < 0)
return (_LDP_ERROR);
if (fstat(fd, &st) != 0)
goto bad_locale;
if (st.st_size <= 0) {
errno = EINVAL;
goto bad_locale;
}
bufsize = namesize + st.st_size;
if ((lbuf = libc_malloc(bufsize)) == NULL) {
errno = ENOMEM;
goto bad_locale;
}
(void) strcpy(lbuf, name);
p = lbuf + namesize;
plim = p + st.st_size;
if (read(fd, p, (size_t)st.st_size) != st.st_size)
goto bad_lbuf;
if (plim[-1] != '\n') {
errno = EINVAL;
goto bad_lbuf;
}
num_lines = split_lines(p, plim);
if (num_lines >= locale_buf_size_max)
num_lines = locale_buf_size_max;
else if (num_lines >= locale_buf_size_min)
num_lines = locale_buf_size_min;
else {
errno = EINVAL;
goto bad_lbuf;
}
(void) close(fd);
*locale_buf = lbuf;
for (p = *locale_buf, i = 0; i < num_lines; i++)
dst_localebuf[i] = (p += strlen(p) + 1);
for (i = num_lines; i < locale_buf_size_max; i++)
dst_localebuf[i] = NULL;
return (_LDP_LOADED);
bad_lbuf:
saverr = errno;
free(lbuf);
errno = saverr;
bad_locale:
saverr = errno;
(void) close(fd);
errno = saverr;
return (_LDP_ERROR);
}
static int
split_lines(char *p, const char *plim)
{
int i;
i = 0;
while (p < plim) {
if (*p == '\n') {
*p = '\0';
i++;
}
p++;
}
return (i);
}