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 --- |