111
112 /*
113 * Scans the specified directory and its subdirectories to find a
114 * zoneinfo file which has the same content as /etc/localtime on Linux
115 * or /usr/share/lib/zoneinfo/localtime on Solaris given in 'buf'.
116 * If file is symbolic link, then the contents it points to are in buf.
117 * Returns a zone ID if found, otherwise, NULL is returned.
118 */
119 static char *
120 findZoneinfoFile(char *buf, size_t size, const char *dir)
121 {
122 DIR *dirp = NULL;
123 struct stat statbuf;
124 struct dirent64 *dp = NULL;
125 struct dirent64 *entry = NULL;
126 char *pathname = NULL;
127 int fd = -1;
128 char *dbuf = NULL;
129 char *tz = NULL;
130 int res;
131
132 dirp = opendir(dir);
133 if (dirp == NULL) {
134 return NULL;
135 }
136
137 entry = (struct dirent64 *) malloc((size_t) pathconf(dir, _PC_NAME_MAX));
138 if (entry == NULL) {
139 (void) closedir(dirp);
140 return NULL;
141 }
142
143 while (readdir64_r(dirp, entry, &dp) == 0 && dp != NULL) {
144 /*
145 * Skip '.' and '..' (and possibly other .* files)
146 */
147 if (dp->d_name[0] == '.') {
148 continue;
149 }
150
151 /*
152 * Skip "ROC", "posixrules", and "localtime".
153 */
154 if ((strcmp(dp->d_name, "ROC") == 0)
155 || (strcmp(dp->d_name, "posixrules") == 0)
156 #if defined(__solaris__)
157 /*
|
111
112 /*
113 * Scans the specified directory and its subdirectories to find a
114 * zoneinfo file which has the same content as /etc/localtime on Linux
115 * or /usr/share/lib/zoneinfo/localtime on Solaris given in 'buf'.
116 * If file is symbolic link, then the contents it points to are in buf.
117 * Returns a zone ID if found, otherwise, NULL is returned.
118 */
119 static char *
120 findZoneinfoFile(char *buf, size_t size, const char *dir)
121 {
122 DIR *dirp = NULL;
123 struct stat statbuf;
124 struct dirent64 *dp = NULL;
125 struct dirent64 *entry = NULL;
126 char *pathname = NULL;
127 int fd = -1;
128 char *dbuf = NULL;
129 char *tz = NULL;
130 int res;
131 long name_max = 0;
132
133 dirp = opendir(dir);
134 if (dirp == NULL) {
135 return NULL;
136 }
137
138 name_max = pathconf(dir, _PC_NAME_MAX);
139 // If pathconf did not work, fall back to NAME_MAX.
140 if (name_max < 0) {
141 name_max = NAME_MAX;
142 }
143 // Some older System V systems have a very small NAME_MAX size of 14; as
144 // there is no way to tell readdir_r the output buffer size, lets enforce
145 // a mimimum buffer size.
146 if (name_max < 1024) {
147 name_max = 1024;
148 }
149
150 entry = (struct dirent64 *)malloc(offsetof(struct dirent64, d_name) + name_max + 1);
151 if (entry == NULL) {
152 (void) closedir(dirp);
153 return NULL;
154 }
155
156 while (readdir64_r(dirp, entry, &dp) == 0 && dp != NULL) {
157 /*
158 * Skip '.' and '..' (and possibly other .* files)
159 */
160 if (dp->d_name[0] == '.') {
161 continue;
162 }
163
164 /*
165 * Skip "ROC", "posixrules", and "localtime".
166 */
167 if ((strcmp(dp->d_name, "ROC") == 0)
168 || (strcmp(dp->d_name, "posixrules") == 0)
169 #if defined(__solaris__)
170 /*
|