1126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood/* 2126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood * 3126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood * Copyright (C) 2008, The Android Open Source Project 4126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood * 5126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood * Licensed under the Apache License, Version 2.0 (the "License"); 6126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood * you may not use this file except in compliance with the License. 7126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood * You may obtain a copy of the License at 8126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood * 9126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood * http://www.apache.org/licenses/LICENSE-2.0 10126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood * 11126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood * Unless required by applicable law or agreed to in writing, software 12126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood * distributed under the License is distributed on an "AS IS" BASIS, 13126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood * See the License for the specific language governing permissions and 15126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood * limitations under the License. 16126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood */ 17126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood 18126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood#include <dirent.h> 19126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood#include <fcntl.h> 20126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood#include <sys/stat.h> 2114df3564fbff5ea9e5fd7d43806258faed46f046Elliott Hughes#include <unistd.h> 22126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood 23126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood#include <diskusage/dirsize.h> 24126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood 25126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwoodint64_t stat_size(struct stat *s) 26126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood{ 272f720f7ec5c9d0b91defc85878e7330b10f8e89aJeff Sharkey return s->st_blocks * 512; 28126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood} 29126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood 30126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwoodint64_t calculate_dir_size(int dfd) 31126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood{ 32126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood int64_t size = 0; 33126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood struct stat s; 34126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood DIR *d; 35126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood struct dirent *de; 36126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood 37126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood d = fdopendir(dfd); 38126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood if (d == NULL) { 39126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood close(dfd); 40126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood return 0; 41126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood } 42126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood 43126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood while ((de = readdir(d))) { 44126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood const char *name = de->d_name; 45126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood if (de->d_type == DT_DIR) { 46126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood int subfd; 47126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood 48126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood /* always skip "." and ".." */ 49126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood if (name[0] == '.') { 50126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood if (name[1] == 0) 51126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood continue; 52126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood if ((name[1] == '.') && (name[2] == 0)) 53126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood continue; 54126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood } 55126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood 562f720f7ec5c9d0b91defc85878e7330b10f8e89aJeff Sharkey if (fstatat(dfd, name, &s, AT_SYMLINK_NOFOLLOW) == 0) { 572f720f7ec5c9d0b91defc85878e7330b10f8e89aJeff Sharkey size += stat_size(&s); 582f720f7ec5c9d0b91defc85878e7330b10f8e89aJeff Sharkey } 59126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood subfd = openat(dfd, name, O_RDONLY | O_DIRECTORY); 60126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood if (subfd >= 0) { 61126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood size += calculate_dir_size(subfd); 62126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood } 632f720f7ec5c9d0b91defc85878e7330b10f8e89aJeff Sharkey } else { 642f720f7ec5c9d0b91defc85878e7330b10f8e89aJeff Sharkey if (fstatat(dfd, name, &s, AT_SYMLINK_NOFOLLOW) == 0) { 652f720f7ec5c9d0b91defc85878e7330b10f8e89aJeff Sharkey size += stat_size(&s); 662f720f7ec5c9d0b91defc85878e7330b10f8e89aJeff Sharkey } 67126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood } 68126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood } 69126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood closedir(d); 70126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood return size; 71126d215667ea6e17226ef3020ef10973bcf5d59cMike Lockwood} 72