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)) ; } }
csync_vio_file_stat_t *csync_vio_local_readdir(csync_vio_handle_t *dhandle) { struct _tdirent *dirent = NULL; dhandle_t *handle = NULL; csync_vio_file_stat_t *file_stat = NULL; handle = (dhandle_t *) dhandle; errno = 0; dirent = _treaddir(handle->dh); if (dirent == NULL) { if (errno) { goto err; } else { return NULL; } } file_stat = csync_vio_file_stat_new(); if (file_stat == NULL) { goto err; } file_stat->name = c_utf8_from_locale(dirent->d_name); file_stat->fields = CSYNC_VIO_FILE_STAT_FIELDS_NONE; /* Check for availability of d_type, see manpage. */ #ifdef _DIRENT_HAVE_D_TYPE switch (dirent->d_type) { case DT_FIFO: case DT_SOCK: case DT_CHR: case DT_BLK: break; case DT_DIR: case DT_REG: file_stat->fields |= CSYNC_VIO_FILE_STAT_FIELDS_TYPE; if (dirent->d_type == DT_DIR) { file_stat->type = CSYNC_VIO_FILE_TYPE_DIRECTORY; } else { file_stat->type = CSYNC_VIO_FILE_TYPE_REGULAR; } break; case DT_UNKNOWN: file_stat->fields |= CSYNC_VIO_FILE_STAT_FIELDS_TYPE; file_stat->type = CSYNC_VIO_FILE_TYPE_UNKNOWN; default: break; } #endif return file_stat; err: SAFE_FREE(file_stat); return NULL; }
void state::process_dir(const tstring &fn) { _TDIR *current_dir; struct _tdirent *entry; if(opt_debug) std::cerr << "*** process_dir(" << global::make_utf8(fn) << ")\n"; if (have_processed_dir(fn)) { ocb.error_filename(fn,"symlink creates cycle"); return ; } if ((current_dir = _topendir(fn.c_str())) == NULL) { ocb.error_filename(fn,"%s", strerror(errno)); return ; } /* 2011-SEP-15 New logic: * 1. Open directory. * 2. Get a list of all the dir entries. * 3. Close the directory. * 4. Process them. */ std::vector<tstring> dir_entries; while ((entry = _treaddir(current_dir)) != NULL) { // ignore . and .. if (is_special_dir(entry->d_name)) continue; // compute full path // don't append if the DIR_SEPARATOR if there is already one there tstring new_file = fn; if (0 == new_file.size() || new_file[new_file.size()-1]!=DIR_SEPARATOR) { new_file.push_back(DIR_SEPARATOR); } new_file.append(entry->d_name); #ifdef _WIN32 /// Windows Junction points if (is_junction_point(new_file)){ continue; } #endif dir_entries.push_back(new_file); } _tclosedir(current_dir); // done with this directory processing_dir(fn); // note that we are now processing a directory for(std::vector<tstring>::const_iterator it = dir_entries.begin();it!=dir_entries.end();it++){ dig_normal(*it); } done_processing_dir(fn); // note that we are done with this directory return ; }
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; }