+
+/*************************************************************************/
+/* START_IP_HEADER */
+/* */
+/* This program is free software: you can redistribute it and/or modify */
+/* it under the terms of the version 3 of the GNU General Public License */
+/* as published by the Free Software Foundation. */
+/* */
+/* This program is distributed in the hope that it will be useful, but */
+/* WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
+/* */
+/* Written by and Copyright (C) Francois Fleuret */
+/* Contact <francois.fleuret@idiap.ch> for comments & bug reports */
+/* */
+/* END_IP_HEADER */
+/*************************************************************************/
+
+#define _BSD_SOURCE
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <dirent.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+
+struct file_with_size {
+ char *filename;
+ size_t size;
+ struct file_with_size *next;
+};
+
+size_t file_or_dir_size(char *name) {
+ DIR *dir;
+ struct dirent *dir_e;
+ struct stat dummy;
+ size_t result;
+ char subname[1024];
+
+ result = 0;
+
+ if(lstat(name, &dummy) != 0) {
+ printf("Can not stat %s (%s).\n", name, strerror(errno));
+ exit (1);
+ }
+
+ if(S_ISLNK(dummy.st_mode)) {
+ return 0;
+ }
+
+ dir = opendir(name);
+
+ if(dir) {
+ while((dir_e = readdir(dir))) {
+ if(strcmp(dir_e->d_name, ".") &&
+ strcmp(dir_e->d_name, "..")) {
+ sprintf(subname, "%s/%s", name, dir_e->d_name);
+ result += file_or_dir_size(subname);
+ }
+ }
+ closedir(dir);
+ } else {
+ if(S_ISREG(dummy.st_mode)) {
+ result += dummy.st_size;
+ }
+ }
+
+ return result;
+}
+
+struct file_with_size *create(char *name, struct file_with_size *current) {
+ struct file_with_size *result;
+ result = malloc(sizeof(struct file_with_size));
+ result->filename = strdup(name);
+ result->size = file_or_dir_size(name);
+ result->next = current;
+ return result;
+}
+
+int main(int argc, char **argv) {
+ int k;
+ struct file_with_size *root;
+
+ root = 0;
+ for(k = 1; k < argc; k++) {
+ root = create(argv[k], root);
+ }
+
+ while(root) {
+ printf("%u %s\n",
+ root->size,
+ root->filename);
+ root = root->next;
+ }
+
+ exit(0);
+}