blob: 7151e3a9cfc007a86f59ad8ab54e9056fbc806b0 [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++;
73 sum = statbuf.st_blocks;
74
75 if (S_ISDIR(statbuf.st_mode)) {
76 DIR *dir;
77 struct dirent *entry;
78
79 dir = opendir(filename);
80 if (!dir) {
81 return 0;
82 }
83 while ((entry = readdir(dir))) {
84 char newfile[PATH_MAX + 1];
85 char *name = entry->d_name;
86
87 if ((strcmp(name, "..") == 0)
88 || (strcmp(name, ".") == 0)) {
89 continue;
90 }
91
92 if (strlen(filename) + strlen(name) + 1 > PATH_MAX) {
93 fprintf(stderr, name_too_long, "du");
94 return 0;
95 }
96 sprintf(newfile, "%s/%s", filename, name);
97
98 sum += du(newfile);
99 }
100 closedir(dir);
101 print(sum, filename);
102 }
103 du_depth--;
104 return sum;
John Beppu0f5e1ab1999-12-09 18:23:54 +0000105}
106
Erik Andersene49d5ec2000-02-08 19:58:47 +0000107int du_main(int argc, char **argv)
108{
109 int i;
110 char opt;
111
112 /* default behaviour */
113 print = print_normal;
114
115 /* parse argv[] */
116 for (i = 1; i < argc; i++) {
117 if (argv[i][0] == '-') {
118 opt = argv[i][1];
119 switch (opt) {
120 case 's':
121 print = print_summary;
122 break;
123 case 'h':
124 usage(du_usage);
125 break;
126 default:
127 fprintf(stderr, "du: invalid option -- %c\n", opt);
128 usage(du_usage);
129 }
130 } else {
131 break;
132 }
133 }
134
135 /* go through remaining args (if any) */
136 if (i >= argc) {
137 du(".");
138 } else {
139 long sum;
140
141 for (; i < argc; i++) {
142 sum = du(argv[i]);
143 if ((sum) && (isDirectory(argv[i], FALSE))) {
144 print_normal(sum, argv[i]);
145 }
146 }
147 }
148
149 exit(0);
150}
151
152/* $Id: du.c,v 1.11 2000/02/08 19:58:47 erik Exp $ */