void _tseekdir (_TDIR * dirp, long lPos) { errno = 0; if (!dirp) { errno = EFAULT; return; } if (lPos < -1) { /* Seeking to an invalid position. */ errno = EINVAL; return; } else if (lPos == -1) { /* Seek past end. */ if (dirp->dd_handle != -1) { _findclose (dirp->dd_handle); } dirp->dd_handle = -1; dirp->dd_stat = -1; } else { /* Rewind and read forward to the appropriate index. */ _trewinddir (dirp); while ((dirp->dd_stat < lPos) && _treaddir (dirp)) ; } }
int c_rmdirs(const char *path) { _TDIR *d; struct _tdirent *dp; csync_stat_t sb; char *fname = NULL; mbchar_t *wfname = NULL; mbchar_t *wpath = c_utf8_to_locale(path); char *rd_name = NULL; if ((d = _topendir(wpath)) != NULL) { while( _tstat(wpath, &sb) == 0) { /* if we can remove the directory we're done */ if (_trmdir(wpath) == 0) { break; } switch (errno) { case ENOTEMPTY: case EEXIST: case EBADF: break; /* continue */ default: _tclosedir(d); c_free_locale_string(wpath); return 0; } while ((dp = _treaddir(d)) != NULL) { size_t len; rd_name = c_utf8_from_locale(dp->d_name); /* skip '.' and '..' */ if( c_streq( rd_name, "." ) || c_streq( rd_name, ".." ) ) { c_free_locale_string(rd_name); continue; } len = strlen(path) + strlen(rd_name) + 2; fname = c_malloc(len); if (fname == NULL) { _tclosedir(d); c_free_locale_string(rd_name); c_free_locale_string(wpath); return -1; } snprintf(fname, len, "%s/%s", path, rd_name); wfname = c_utf8_to_locale(fname); /* stat the file */ if (_tstat(wfname, &sb) != -1) { #ifdef __unix__ if (S_ISDIR(sb.st_mode) && !S_ISLNK(sb.st_mode)) { #else if (S_ISDIR(sb.st_mode)) { #endif if (_trmdir(wfname) < 0) { /* can't be deleted */ if (errno == EACCES) { _tclosedir(d); SAFE_FREE(fname); c_free_locale_string(wfname); c_free_locale_string(rd_name); c_free_locale_string(wpath); return -1; } c_rmdirs(fname); } } else { _tunlink(wfname); } } /* lstat */ SAFE_FREE(fname); c_free_locale_string(wfname); c_free_locale_string(rd_name); } /* readdir */ _trewinddir(d); } } else { c_free_locale_string(wpath); return -1; } c_free_locale_string(wpath); _tclosedir(d); return 0; }