static int64_t calculate_directory_size(char *path) { int64_t result = 0; DIR *d; struct dirent *entry; //DPRINTF("Calculate %s\n", path); d = opendir(path); if (!d) return -1; while ((entry = readdir(d))) { if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0 || strlen(entry->d_name) == 0) continue; //DPRINTF("name: %s\n", entry->d_name); file_stat_t st; char newpath[strlen(path)+strlen(entry->d_name)+2]; sprintf(newpath, "%s/%s", path, entry->d_name); if (stat_file(newpath, &st) < 0) { DPRINTF("calculate_directory_size: stat failed on %s\n", newpath); result = -1; break; } if ((st.mode & S_IFDIR) == S_IFDIR) { int64_t temp = calculate_directory_size(newpath); if (temp < 0) { result = temp; break; } result += temp; } else if ((st.mode & S_IFREG) == S_IFREG) { result += st.file_size; } } closedir(d); return result; }
static int process_get_dir_size_cmd(client_t *client, netiso_get_dir_size_cmd *cmd) { netiso_get_dir_size_result result; char *dirpath; uint16_t dp_len; int ret; dp_len = BE16(cmd->dp_len); dirpath = (char *)malloc(dp_len+1); if (!dirpath) { DPRINTF("CRITICAL: memory allocation error\n"); return -1; } dirpath[dp_len] = 0; ret = recv_all(client->s, (char *)dirpath, dp_len); if (ret != dp_len) { DPRINTF("recv failed, getting dirname for get_dir_size: %d %d\n", ret, get_network_error()); free(dirpath); return -1; } dirpath = translate_path(dirpath, 1, 1, NULL); if (!dirpath) { DPRINTF("Path cannot be translated. Connection with this client will be aborted.\n"); return -1; } DPRINTF("get_dir_size %s\n", dirpath); result.dir_size = BE64(calculate_directory_size(dirpath)); free(dirpath); ret = send(client->s, (char *)&result, sizeof(result), 0); if (ret != sizeof(result)) { DPRINTF("get_dir_size, send result error: %d %d\n", ret, get_network_error()); return -1; } return 0; }
static int64_t calculate_directory_size(char *path) { int64_t result = 0; DIR *d; struct dirent *entry; char *newpath; //DPRINTF("Calculate %s\n", path); file_stat_t st; if(stat_file(path, &st) < 0) return -1; d = opendir(path); if(!d) return -1; size_t d_name_len, path_len; path_len = strlen(path); while ((entry = readdir(d))) { if(IS_PARENT_DIR(entry->d_name)) continue; d_name_len = strlen(entry->d_name); if(IS_RANGE(d_name_len, 1, 65535)) { //DPRINTF("name: %s\n", entry->d_name); newpath = (char *)malloc(path_len + d_name_len + 2); if(!newpath) break; sprintf(newpath, "%s/%s", path, entry->d_name); if(stat_file(newpath, &st) < 0) { DPRINTF("calculate_directory_size: stat failed on %s\n", newpath); result = -1; break; } if((st.mode & S_IFDIR) == S_IFDIR) { int64_t temp = calculate_directory_size(newpath); if(temp < 0) { result = temp; break; } result += temp; } else if((st.mode & S_IFREG) == S_IFREG) { result += st.file_size; } free(newpath); } } if(newpath) free(newpath); closedir(d); return result; }