Deleted Added
full compact
ldpart.c (92986) ldpart.c (101307)
1/*
2 * Copyright (c) 2000, 2001 Alexey Zelkin <phantom@FreeBSD.org>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 11 unchanged lines hidden (view full) ---

20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26
27#include <sys/cdefs.h>
1/*
2 * Copyright (c) 2000, 2001 Alexey Zelkin <phantom@FreeBSD.org>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 11 unchanged lines hidden (view full) ---

20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26
27#include <sys/cdefs.h>
28__FBSDID("$FreeBSD: head/lib/libc/locale/ldpart.c 92986 2002-03-22 21:53:29Z obrien $");
28__FBSDID("$FreeBSD: head/lib/libc/locale/ldpart.c 101307 2002-08-04 09:37:28Z ache $");
29
30#include "namespace.h"
31#include <sys/types.h>
32#include <sys/stat.h>
33#include <sys/syslimits.h>
29
30#include "namespace.h"
31#include <sys/types.h>
32#include <sys/stat.h>
33#include <sys/syslimits.h>
34#include <errno.h>
34#include <fcntl.h>
35#include <stdlib.h>
36#include <string.h>
37#include <unistd.h>
38#include "un-namespace.h"
39
40#include "setlocale.h"
41#include "ldpart.h"
42
43static int split_lines(char *, const char *);
44static void set_from_buf(const char *, int, const char **);
45
46int
47__part_load_locale(const char *name,
48 int *using_locale,
49 char *locale_buf,
50 const char *category_filename,
51 int locale_buf_size_max,
52 int locale_buf_size_min,
35#include <fcntl.h>
36#include <stdlib.h>
37#include <string.h>
38#include <unistd.h>
39#include "un-namespace.h"
40
41#include "setlocale.h"
42#include "ldpart.h"
43
44static int split_lines(char *, const char *);
45static void set_from_buf(const char *, int, const char **);
46
47int
48__part_load_locale(const char *name,
49 int *using_locale,
50 char *locale_buf,
51 const char *category_filename,
52 int locale_buf_size_max,
53 int locale_buf_size_min,
53 const char **dst_localebuf) {
54
54 const char **dst_localebuf)
55{
55 static char locale_buf_C[] = "C";
56 static int num_lines;
56 static char locale_buf_C[] = "C";
57 static int num_lines;
57
58 int saverr;
58 int fd;
59 char *lbuf;
60 char *p;
61 const char *plim;
62 char filename[PATH_MAX];
63 struct stat st;
64 size_t namesize;
65 size_t bufsize;
66 int save_using_locale;
67
68 save_using_locale = *using_locale;
69 *using_locale = 0;
70
59 int fd;
60 char *lbuf;
61 char *p;
62 const char *plim;
63 char filename[PATH_MAX];
64 struct stat st;
65 size_t namesize;
66 size_t bufsize;
67 int save_using_locale;
68
69 save_using_locale = *using_locale;
70 *using_locale = 0;
71
71 if (name == NULL)
72 goto no_locale;
72 /* 'name' must be already checked. */
73
74 if (!strcmp(name, "C") || !strcmp(name, "POSIX"))
75 return 0;
76
77 /*
78 * If the locale name is the same as our cache, use the cache.
79 */
80 lbuf = locale_buf;
81 if (lbuf != NULL && strcmp(name, lbuf) == 0) {
82 set_from_buf(lbuf, num_lines, dst_localebuf);
83 *using_locale = 1;
84 return 0;
85 }
86
87 /*
88 * Slurp the locale file into the cache.
89 */
90 namesize = strlen(name) + 1;
91
73
74 if (!strcmp(name, "C") || !strcmp(name, "POSIX"))
75 return 0;
76
77 /*
78 * If the locale name is the same as our cache, use the cache.
79 */
80 lbuf = locale_buf;
81 if (lbuf != NULL && strcmp(name, lbuf) == 0) {
82 set_from_buf(lbuf, num_lines, dst_localebuf);
83 *using_locale = 1;
84 return 0;
85 }
86
87 /*
88 * Slurp the locale file into the cache.
89 */
90 namesize = strlen(name) + 1;
91
92 if (!_PathLocale)
93 goto no_locale;
92 /* 'PathLocale' must be already set & checked. */
93
94 /* Range checking not needed, 'name' size is limited */
95 strcpy(filename, _PathLocale);
96 strcat(filename, "/");
97 strcat(filename, name);
98 strcat(filename, "/");
99 strcat(filename, category_filename);
100 fd = _open(filename, O_RDONLY);
101 if (fd < 0)
102 goto no_locale;
103 if (_fstat(fd, &st) != 0)
104 goto bad_locale;
94 /* Range checking not needed, 'name' size is limited */
95 strcpy(filename, _PathLocale);
96 strcat(filename, "/");
97 strcat(filename, name);
98 strcat(filename, "/");
99 strcat(filename, category_filename);
100 fd = _open(filename, O_RDONLY);
101 if (fd < 0)
102 goto no_locale;
103 if (_fstat(fd, &st) != 0)
104 goto bad_locale;
105 if (st.st_size <= 0)
105 if (st.st_size <= 0) {
106 errno = EFTYPE;
106 goto bad_locale;
107 goto bad_locale;
108 }
107 bufsize = namesize + st.st_size;
108 locale_buf = NULL;
109 lbuf = (lbuf == NULL || lbuf == locale_buf_C) ?
110 malloc(bufsize) : reallocf(lbuf, bufsize);
111 if (lbuf == NULL)
112 goto bad_locale;
113 (void) strcpy(lbuf, name);
114 p = lbuf + namesize;
115 plim = p + st.st_size;
116 if (_read(fd, p, (size_t) st.st_size) != st.st_size)
117 goto bad_lbuf;
118 if (_close(fd) != 0)
119 goto bad_lbuf;
120 /*
121 * Parse the locale file into localebuf.
122 */
109 bufsize = namesize + st.st_size;
110 locale_buf = NULL;
111 lbuf = (lbuf == NULL || lbuf == locale_buf_C) ?
112 malloc(bufsize) : reallocf(lbuf, bufsize);
113 if (lbuf == NULL)
114 goto bad_locale;
115 (void) strcpy(lbuf, name);
116 p = lbuf + namesize;
117 plim = p + st.st_size;
118 if (_read(fd, p, (size_t) st.st_size) != st.st_size)
119 goto bad_lbuf;
120 if (_close(fd) != 0)
121 goto bad_lbuf;
122 /*
123 * Parse the locale file into localebuf.
124 */
123 if (plim[-1] != '\n')
125 if (plim[-1] != '\n') {
126 errno = EFTYPE;
124 goto bad_lbuf;
127 goto bad_lbuf;
128 }
125 num_lines = split_lines(p, plim);
126 if (num_lines >= locale_buf_size_max)
127 num_lines = locale_buf_size_max;
128 else if (num_lines >= locale_buf_size_min)
129 num_lines = locale_buf_size_min;
129 num_lines = split_lines(p, plim);
130 if (num_lines >= locale_buf_size_max)
131 num_lines = locale_buf_size_max;
132 else if (num_lines >= locale_buf_size_min)
133 num_lines = locale_buf_size_min;
130 else
134 else {
135 errno = EFTYPE;
131 goto reset_locale;
136 goto reset_locale;
137 }
132 set_from_buf(lbuf, num_lines, dst_localebuf);
133 /*
134 * Record the successful parse in the cache.
135 */
136 locale_buf = lbuf;
137
138 *using_locale = 1;
139 return 0;
140
141reset_locale:
142 locale_buf = locale_buf_C;
143 save_using_locale = 0;
144bad_lbuf:
138 set_from_buf(lbuf, num_lines, dst_localebuf);
139 /*
140 * Record the successful parse in the cache.
141 */
142 locale_buf = lbuf;
143
144 *using_locale = 1;
145 return 0;
146
147reset_locale:
148 locale_buf = locale_buf_C;
149 save_using_locale = 0;
150bad_lbuf:
145 free(lbuf);
151 saverr = errno; free(lbuf); errno = saverr;
146bad_locale:
152bad_locale:
147 (void)_close(fd);
153 saverr = errno; (void)_close(fd); errno = saverr;
148no_locale:
149 *using_locale = save_using_locale;
150 return -1;
151}
152
153static int
154split_lines(char *p, const char *plim) {
155

--- 19 unchanged lines hidden ---
154no_locale:
155 *using_locale = save_using_locale;
156 return -1;
157}
158
159static int
160split_lines(char *p, const char *plim) {
161

--- 19 unchanged lines hidden ---