blob: b17f46d47805f98bf9a9e2e9b79e0009b1f448b9 [file] [log] [blame]
Alistair Delvabeaee832021-02-24 11:27:23 -08001/* Copyright 1997,2000-2002,2009 Alain Knaff.
2 * This file is part of mtools.
3 *
4 * Mtools is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * Mtools is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with Mtools. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * mdu.c:
18 * Display the space occupied by an MSDOS directory
19 */
20
21#include "sysincludes.h"
22#include "msdos.h"
23#include "vfat.h"
24#include "mtools.h"
25#include "file.h"
26#include "mainloop.h"
27#include "fs.h"
28#include "codepage.h"
29
30
31typedef struct Arg_t {
32 int all;
33 int inDir;
34 int summary;
35 struct Arg_t *parent;
36 char *target;
37 char *path;
38 unsigned int blocks;
39 MainParam_t mp;
40} Arg_t;
41
42static void usage(int ret) NORETURN;
43static void usage(int ret)
44{
45 fprintf(stderr, "Mtools version %s, dated %s\n",
46 mversion, mdate);
47 fprintf(stderr, "Usage: %s: msdosdirectory\n",
48 progname);
49 exit(ret);
50}
51
52static int file_mdu(direntry_t *entry, MainParam_t *mp)
53{
54 unsigned int blocks;
55 Arg_t * arg = (Arg_t *) (mp->arg);
56
57 blocks = countBlocks(entry->Dir,getStart(entry->Dir, &entry->dir));
58 if(arg->all || !arg->inDir) {
59 fprintPwd(stdout, entry,0);
60 printf(" %d\n", blocks);
61 }
62 arg->blocks += blocks;
63 return GOT_ONE;
64}
65
66
67static int dir_mdu(direntry_t *entry, MainParam_t *mp)
68{
69 Arg_t *parentArg = (Arg_t *) (mp->arg);
70 Arg_t arg;
71 int ret;
Yi Kong39bbd962022-01-09 19:41:38 +080072
Alistair Delvabeaee832021-02-24 11:27:23 -080073 arg = *parentArg;
74 arg.mp.arg = (void *) &arg;
75 arg.parent = parentArg;
76 arg.inDir = 1;
77
78 /* account for the space occupied by the directory itself */
79 if(!isRootDir(entry->Dir)) {
80 arg.blocks = countBlocks(entry->Dir,
81 getStart(entry->Dir, &entry->dir));
82 } else {
83 arg.blocks = 0;
84 }
85
86 /* recursion */
87 ret = mp->loop(mp->File, &arg.mp, "*");
88 if(!arg.summary || !parentArg->inDir) {
89 fprintPwd(stdout, entry,0);
90 printf(" %d\n", arg.blocks);
91 }
92 arg.parent->blocks += arg.blocks;
93 return ret;
94}
95
96void mdu(int argc, char **argv, int type UNUSEDP) NORETURN;
97void mdu(int argc, char **argv, int type UNUSEDP)
98{
99 Arg_t arg;
100 int c;
101
102 arg.all = 0;
103 arg.inDir = 0;
104 arg.summary = 0;
105 if(helpFlag(argc, argv))
106 usage(0);
107 while ((c = getopt(argc, argv, "i:ash")) != EOF) {
108 switch (c) {
109 case 'i':
110 set_cmd_line_image(optarg);
111 break;
112 case 'a':
113 arg.all = 1;
114 break;
115 case 's':
116 arg.summary = 1;
117 break;
118 case 'h':
119 usage(0);
120 case '?':
121 usage(1);
122 }
123 }
124
125 if (optind >= argc)
126 usage(1);
127
128 if(arg.summary && arg.all) {
129 fprintf(stderr,"-a and -s options are mutually exclusive\n");
130 usage(1);
131 }
132
133 init_mp(&arg.mp);
134 arg.mp.callback = file_mdu;
135 arg.mp.openflags = O_RDONLY;
136 arg.mp.dirCallback = dir_mdu;
137
138 arg.mp.arg = (void *) &arg;
139 arg.mp.lookupflags = ACCEPT_PLAIN | ACCEPT_DIR | DO_OPEN_DIRS | NO_DOTS;
140 exit(main_loop(&arg.mp, argv + optind, argc - optind));
141}