blob: 7b5acb490dd6a58c878b6455cd5693297e00e20a [file] [log] [blame]
Erik Andersene49d5ec2000-02-08 19:58:47 +00001/* vi: set sw=4 ts=4: */
John Beppu0f5e1ab1999-12-09 18:23:54 +00002/*
3 * Mini du implementation for busybox
4 *
5 *
6 * Copyright (C) 1999 by Lineo, inc.
Eric Andersen70e2f0b1999-12-10 06:45:42 +00007 * Written by John Beppu <beppu@lineo.com>
John Beppu0f5e1ab1999-12-09 18:23:54 +00008 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 *
23 */
24
25#include "internal.h"
Erik Andersenfac10d72000-02-07 05:29:42 +000026#define BB_DECLARE_EXTERN
27#define bb_need_name_too_long
28#include "messages.c"
29
John Beppu0f5e1ab1999-12-09 18:23:54 +000030#include <sys/types.h>
31#include <fcntl.h>
32#include <dirent.h>
33#include <stdio.h>
John Beppu98355411999-12-10 07:40:08 +000034#include <errno.h>
Erik Andersene49d5ec2000-02-08 19:58:47 +000035#include <sys/param.h> /* for PATH_MAX */
John Beppu0f5e1ab1999-12-09 18:23:54 +000036
Erik Andersene49d5ec2000-02-08 19:58:47 +000037typedef void (Display) (long, char *);
John Beppu0f5e1ab1999-12-09 18:23:54 +000038
John Beppue1618e41999-12-15 18:52:17 +000039static const char du_usage[] =
John Beppue1618e41999-12-15 18:52:17 +000040
Erik Andersene49d5ec2000-02-08 19:58:47 +000041 "du [OPTION]... [FILE]...\n\n"
42 "\t-s\tdisplay only a total for each argument\n";
John Beppue1618e41999-12-15 18:52:17 +000043
Erik Andersene49d5ec2000-02-08 19:58:47 +000044static int du_depth = 0;
John Beppue1618e41999-12-15 18:52:17 +000045
Erik Andersene49d5ec2000-02-08 19:58:47 +000046static Display *print;
47
48static void print_normal(long size, char *filename)
John Beppu0f5e1ab1999-12-09 18:23:54 +000049{
Erik Andersene49d5ec2000-02-08 19:58:47 +000050 fprintf(stdout, "%-7ld %s\n", size, filename);
John Beppu0f5e1ab1999-12-09 18:23:54 +000051}
52
Erik Andersene49d5ec2000-02-08 19:58:47 +000053static void print_summary(long size, char *filename)
John Beppue1618e41999-12-15 18:52:17 +000054{
Erik Andersene49d5ec2000-02-08 19:58:47 +000055 if (du_depth == 1) {
56 print_normal(size, filename);
57 }
John Beppue1618e41999-12-15 18:52:17 +000058}
59
60
John Beppu0f5e1ab1999-12-09 18:23:54 +000061/* tiny recursive du */
Erik Andersene49d5ec2000-02-08 19:58:47 +000062static long du(char *filename)
John Beppu0f5e1ab1999-12-09 18:23:54 +000063{
Erik Andersene49d5ec2000-02-08 19:58:47 +000064 struct stat statbuf;
Erik Andersenfac10d72000-02-07 05:29:42 +000065 long sum;
John Beppu14c82b61999-12-10 06:15:27 +000066
Erik Andersene49d5ec2000-02-08 19:58:47 +000067 if ((lstat(filename, &statbuf)) != 0) {
68 fprintf(stdout, "du: %s: %s\n", filename, strerror(errno));
69 return 0;
70 }
71
72 du_depth++;
John Beppu08c965a2000-02-13 04:10:57 +000073 sum = (statbuf.st_blocks >> 1);
Erik Andersene49d5ec2000-02-08 19:58:47 +000074
Erik Andersen9ffdaa62000-02-11 21:55:04 +000075 /* Don't add in stuff pointed to by links */
76 if (S_ISLNK(statbuf.st_mode)) {
77 return 0;
78 }
Erik Andersene49d5ec2000-02-08 19:58:47 +000079 if (S_ISDIR(statbuf.st_mode)) {
80 DIR *dir;
81 struct dirent *entry;
82
83 dir = opendir(filename);
84 if (!dir) {
85 return 0;
86 }
87 while ((entry = readdir(dir))) {
88 char newfile[PATH_MAX + 1];
89 char *name = entry->d_name;
90
91 if ((strcmp(name, "..") == 0)
92 || (strcmp(name, ".") == 0)) {
93 continue;
94 }
95
96 if (strlen(filename) + strlen(name) + 1 > PATH_MAX) {
97 fprintf(stderr, name_too_long, "du");
98 return 0;
99 }
100 sprintf(newfile, "%s/%s", filename, name);
101
102 sum += du(newfile);
103 }
104 closedir(dir);
105 print(sum, filename);
106 }
107 du_depth--;
108 return sum;
John Beppu0f5e1ab1999-12-09 18:23:54 +0000109}
110
Erik Andersene49d5ec2000-02-08 19:58:47 +0000111int du_main(int argc, char **argv)
112{
113 int i;
114 char opt;
115
116 /* default behaviour */
117 print = print_normal;
118
119 /* parse argv[] */
120 for (i = 1; i < argc; i++) {
121 if (argv[i][0] == '-') {
122 opt = argv[i][1];
123 switch (opt) {
124 case 's':
125 print = print_summary;
126 break;
127 case 'h':
128 usage(du_usage);
129 break;
130 default:
131 fprintf(stderr, "du: invalid option -- %c\n", opt);
132 usage(du_usage);
133 }
134 } else {
135 break;
136 }
137 }
138
139 /* go through remaining args (if any) */
140 if (i >= argc) {
141 du(".");
142 } else {
143 long sum;
144
145 for (; i < argc; i++) {
146 sum = du(argv[i]);
Erik Andersen9ffdaa62000-02-11 21:55:04 +0000147 if ((sum) && (isDirectory(argv[i], FALSE, NULL))) {
Erik Andersene49d5ec2000-02-08 19:58:47 +0000148 print_normal(sum, argv[i]);
149 }
150 }
151 }
152
153 exit(0);
154}
155
John Beppu08c965a2000-02-13 04:10:57 +0000156/* $Id: du.c,v 1.13 2000/02/13 04:10:57 beppu Exp $ */