blob: e2cf3f7c09408d4d96b4219aee50d48d40626693 [file] [log] [blame]
John Beppu0f5e1ab1999-12-09 18:23:54 +00001/*
2 * Mini du implementation for busybox
3 *
4 *
5 * Copyright (C) 1999 by Lineo, inc.
Eric Andersen70e2f0b1999-12-10 06:45:42 +00006 * Written by John Beppu <beppu@lineo.com>
John Beppu0f5e1ab1999-12-09 18:23:54 +00007 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 *
22 */
23
24#include "internal.h"
Erik Andersenfac10d72000-02-07 05:29:42 +000025#define BB_DECLARE_EXTERN
26#define bb_need_name_too_long
27#include "messages.c"
28
John Beppu0f5e1ab1999-12-09 18:23:54 +000029#include <sys/types.h>
30#include <fcntl.h>
31#include <dirent.h>
32#include <stdio.h>
John Beppu98355411999-12-10 07:40:08 +000033#include <errno.h>
Erik Andersenfac10d72000-02-07 05:29:42 +000034#include <sys/param.h> /* for PATH_MAX */
John Beppu0f5e1ab1999-12-09 18:23:54 +000035
Erik Andersenfac10d72000-02-07 05:29:42 +000036typedef void (Display)(long, char *);
John Beppu0f5e1ab1999-12-09 18:23:54 +000037
John Beppue1618e41999-12-15 18:52:17 +000038static const char du_usage[] =
Erik Andersen5509af72000-01-23 18:19:02 +000039"du [OPTION]... [FILE]...\n\n"
John Beppue1618e41999-12-15 18:52:17 +000040"\t-s\tdisplay only a total for each argument\n"
41;
42
43static int du_depth = 0;
44
45static Display *print;
46
John Beppu0f5e1ab1999-12-09 18:23:54 +000047static void
Erik Andersenfac10d72000-02-07 05:29:42 +000048print_normal(long size, char *filename)
John Beppu0f5e1ab1999-12-09 18:23:54 +000049{
Erik Andersenfac10d72000-02-07 05:29:42 +000050 fprintf(stdout, "%-7ld %s\n", size, filename);
John Beppu0f5e1ab1999-12-09 18:23:54 +000051}
52
John Beppue1618e41999-12-15 18:52:17 +000053static void
Erik Andersenfac10d72000-02-07 05:29:42 +000054print_summary(long size, char *filename)
John Beppue1618e41999-12-15 18:52:17 +000055{
56 if (du_depth == 1) {
57 print_normal(size, filename);
58 }
59}
60
61
John Beppu0f5e1ab1999-12-09 18:23:54 +000062/* tiny recursive du */
Erik Andersenfac10d72000-02-07 05:29:42 +000063static long
John Beppu14c82b61999-12-10 06:15:27 +000064du(char *filename)
John Beppu0f5e1ab1999-12-09 18:23:54 +000065{
66 struct stat statbuf;
Erik Andersenfac10d72000-02-07 05:29:42 +000067 long sum;
John Beppu0f5e1ab1999-12-09 18:23:54 +000068
John Beppu98355411999-12-10 07:40:08 +000069 if ((lstat(filename, &statbuf)) != 0) {
70 fprintf(stdout, "du: %s: %s\n", filename, strerror(errno));
71 return 0;
72 }
John Beppue1618e41999-12-15 18:52:17 +000073
74 du_depth++;
John Beppu0f5e1ab1999-12-09 18:23:54 +000075 sum = statbuf.st_blocks;
76
77 if (S_ISDIR(statbuf.st_mode)) {
78 DIR *dir;
79 struct dirent *entry;
80
81 dir = opendir(filename);
82 if (!dir) { return 0; }
83 while ((entry = readdir(dir))) {
Erik Andersenfac10d72000-02-07 05:29:42 +000084 char newfile[PATH_MAX + 1];
John Beppu0f5e1ab1999-12-09 18:23:54 +000085 char *name = entry->d_name;
86
87 if ( (strcmp(name, "..") == 0)
88 || (strcmp(name, ".") == 0))
89 { continue; }
90
Erik Andersenfac10d72000-02-07 05:29:42 +000091 if (strlen(filename) + strlen(name) + 1 > PATH_MAX) {
92 fprintf(stderr, name_too_long, "du");
93 return 0;
94 }
John Beppu0f5e1ab1999-12-09 18:23:54 +000095 sprintf(newfile, "%s/%s", filename, name);
Erik Andersenfac10d72000-02-07 05:29:42 +000096
John Beppu14c82b61999-12-10 06:15:27 +000097 sum += du(newfile);
John Beppu0f5e1ab1999-12-09 18:23:54 +000098 }
99 closedir(dir);
100 print(sum, filename);
101 }
John Beppue1618e41999-12-15 18:52:17 +0000102 du_depth--;
John Beppu0f5e1ab1999-12-09 18:23:54 +0000103 return sum;
104}
105
106int
107du_main(int argc, char **argv)
108{
John Beppu14c82b61999-12-10 06:15:27 +0000109 int i;
110 char opt;
111
John Beppue1618e41999-12-15 18:52:17 +0000112 /* default behaviour */
113 print = print_normal;
114
John Beppu14c82b61999-12-10 06:15:27 +0000115 /* 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':
John Beppue1618e41999-12-15 18:52:17 +0000121 print = print_summary;
John Beppu14c82b61999-12-10 06:15:27 +0000122 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 {
Erik Andersenfac10d72000-02-07 05:29:42 +0000139 long sum;
John Beppu14c82b61999-12-10 06:15:27 +0000140 for ( ; i < argc; i++) {
John Beppue1618e41999-12-15 18:52:17 +0000141 sum = du(argv[i]);
Erik Andersenfac10d72000-02-07 05:29:42 +0000142 if ((sum) && (isDirectory(argv[i], FALSE))) { print_normal(sum, argv[i]); }
John Beppu14c82b61999-12-10 06:15:27 +0000143 }
144 }
145
John Beppu0f5e1ab1999-12-09 18:23:54 +0000146 exit(0);
147}
148
Erik Andersenfac10d72000-02-07 05:29:42 +0000149/* $Id: du.c,v 1.10 2000/02/07 05:29:42 erik Exp $ */