/* browser_vfs_opendir */ DIR * browser_vfs_opendir(char const * filename, struct stat * st) { DIR * dir; int fd; #ifdef DEBUG fprintf(stderr, "DEBUG: %s(\"%s\", %p)\n", __func__, filename, st); #endif if(st == NULL) return opendir(filename); #if defined(__sun) if((fd = open(filename, O_RDONLY)) < 0 || (dir = fdopendir(fd)) == NULL) { if(fd >= 0) close(fd); return NULL; } #else if((dir = opendir(filename)) == NULL) return NULL; fd = dirfd(dir); #endif if(fstat(fd, st) != 0) { browser_vfs_closedir(dir); return NULL; } return dir; }
static int _single_recurse(Copy * copy, char const * src, char const * dst, mode_t mode) { int ret = 0; Copy copy2; Prefs prefs2 = *(copy->prefs); size_t srclen; size_t dstlen; DIR * dir; struct dirent * de; char * ssrc = NULL; char * sdst = NULL; char * p; memcpy(©2, copy, sizeof(copy2)); copy2.prefs = &prefs2; if(mkdir(dst, mode) != 0 && errno != EEXIST) return _copy_filename_error(copy, dst, 1); srclen = strlen(src); dstlen = strlen(dst); if((dir = browser_vfs_opendir(src, NULL)) == NULL) return _copy_filename_error(copy, src, 1); prefs2 |= (prefs2 & PREFS_H) ? PREFS_P : 0; while((de = browser_vfs_readdir(dir)) != NULL) { if(de->d_name[0] == '.' && (de->d_name[1] == '\0' || (de->d_name[1] == '.' && de->d_name[2] == '\0'))) continue; if((p = realloc(ssrc, srclen + strlen(de->d_name) + 2)) == NULL) { ret |= _copy_filename_error(copy, src, 1); continue; } ssrc = p; if((p = realloc(sdst, dstlen + strlen(de->d_name) + 2)) == NULL) { ret |= _copy_filename_error(copy, src, 1); continue; } sdst = p; sprintf(ssrc, "%s/%s", src, de->d_name); sprintf(sdst, "%s/%s", dst, de->d_name); ret |= _copy_single(©2, ssrc, sdst); } browser_vfs_closedir(dir); free(ssrc); free(sdst); return ret; }