static const char* scan_timezone_dir( ScanDataRec* scan, char* top, int depth ) { DIR* d = opendir( scan->path ); const char* result = NULL; D( "%s: entering '%s\n", __FUNCTION__, scan->path ); if (d != NULL) { struct dirent* ent; while ((ent = readdir(d)) != NULL) { struct stat ent_st; char* p = top; if (ent->d_name[0] == '.') /* avoid hidden and special files */ continue; p = bufprint( p, scan->path_end, "/%s", ent->d_name ); if (p >= scan->path_end) continue; //D( "%s: scanning '%s'\n", __FUNCTION__, scan->path ); if ( stat( scan->path, &ent_st ) < 0 ) continue; if ( S_ISDIR(ent_st.st_mode) && depth < 2 ) { //D( "%s: directory '%s'\n", __FUNCTION__, scan->path ); result = scan_timezone_dir( scan, p, depth + 1 ); if (result != NULL) break; } else if ( S_ISREG(ent_st.st_mode) && (depth >= 1 && depth <= 2) ) { char* name = scan->path_root + 1; if ( check_timezone_is_zoneinfo( name ) ) { if (compare_timezone_to_localtime( scan, scan->path )) { result = strdup( name ); D( "%s: found '%s'\n", __FUNCTION__, result ); break; } } else { //D( "%s: ignoring '%s'\n", __FUNCTION__, scan->path ); } } } closedir(d); } return result; }
static const char* scan_timezone_dir( ScanDataRec* scan, char* top, int depth ) { DIR* d = opendir( scan->path ); const char* result = NULL; D( "%s: entering '%s\n", __FUNCTION__, scan->path ); if (d != NULL) { struct dirent* ent; while ((ent = readdir(d)) != NULL) { struct stat ent_st; char* p = top; if (ent->d_name[0] == '.') /* avoid hidden and special files */ continue; p = bufprint( p, scan->path_end, "/%s", ent->d_name ); if (p >= scan->path_end) continue; //D( "%s: scanning '%s'\n", __FUNCTION__, scan->path ); // Important: use lstat() instead of stat() because recent // Ubuntu distributions creates directories full of links, e.g. // /usr/share/info/posix/Australia/Sydney -> ../../Australia/Sydney // and we want to ignore them. if ( lstat( scan->path, &ent_st ) < 0 ) continue; if ( S_ISDIR(ent_st.st_mode) && depth < 2 ) { //D( "%s: directory '%s'\n", __FUNCTION__, scan->path ); result = scan_timezone_dir( scan, p, depth + 1 ); if (result != NULL) break; } else if ( S_ISREG(ent_st.st_mode) && (depth >= 1 && depth <= 2) ) { char* name = scan->path_root + 1; if ( check_timezone_is_zoneinfo( name ) ) { if (compare_timezone_to_localtime( scan, scan->path )) { result = strdup( name ); D( "%s: found '%s'\n", __FUNCTION__, result ); break; } } else { //D( "%s: ignoring '%s'\n", __FUNCTION__, scan->path ); } } } closedir(d); } return result; }