/* Copyright 1997,2000-2002,2009 Alain Knaff. * This file is part of mtools. * * Mtools is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Mtools 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 Mtools. If not, see . * * mdu.c: * Display the space occupied by an MSDOS directory */ #include "sysincludes.h" #include "mtools.h" #include "file.h" #include "mainloop.h" #include "fs.h" typedef struct Arg_t { int all; int inDir; int summary; struct Arg_t *parent; char *target; char *path; unsigned int blocks; MainParam_t mp; } Arg_t; static void usage(int ret) NORETURN; static void usage(int ret) { fprintf(stderr, "Mtools version %s, dated %s\n", mversion, mdate); fprintf(stderr, "Usage: %s: msdosdirectory\n", progname); exit(ret); } static int file_mdu(direntry_t *entry, MainParam_t *mp) { unsigned int blocks; Arg_t * arg = (Arg_t *) (mp->arg); blocks = countBlocks(entry->Dir,getStart(entry->Dir, &entry->dir)); if(arg->all || !arg->inDir) { fprintPwd(stdout, entry,0); printf(" %d\n", blocks); } arg->blocks += blocks; return GOT_ONE; } static int dir_mdu(direntry_t *entry, MainParam_t *mp) { Arg_t *parentArg = (Arg_t *) (mp->arg); Arg_t arg; int ret; arg = *parentArg; arg.mp.arg = (void *) &arg; arg.parent = parentArg; arg.inDir = 1; /* account for the space occupied by the directory itself */ if(!isRootDir(entry->Dir)) { arg.blocks = countBlocks(entry->Dir, getStart(entry->Dir, &entry->dir)); } else { arg.blocks = 0; } /* recursion */ ret = mp->loop(mp->File, &arg.mp, "*"); if(!arg.summary || !parentArg->inDir) { fprintPwd(stdout, entry,0); printf(" %d\n", arg.blocks); } arg.parent->blocks += arg.blocks; return ret; } void mdu(int argc, char **argv, int type UNUSEDP) NORETURN; void mdu(int argc, char **argv, int type UNUSEDP) { Arg_t arg; int c; arg.all = 0; arg.inDir = 0; arg.summary = 0; if(helpFlag(argc, argv)) usage(0); while ((c = getopt(argc, argv, "i:ash")) != EOF) { switch (c) { case 'i': set_cmd_line_image(optarg); break; case 'a': arg.all = 1; break; case 's': arg.summary = 1; break; case 'h': usage(0); case '?': usage(1); } } if (optind >= argc) usage(1); if(arg.summary && arg.all) { fprintf(stderr,"-a and -s options are mutually exclusive\n"); usage(1); } init_mp(&arg.mp); arg.mp.callback = file_mdu; arg.mp.openflags = O_RDONLY; arg.mp.dirCallback = dir_mdu; arg.mp.arg = (void *) &arg; arg.mp.lookupflags = ACCEPT_PLAIN | ACCEPT_DIR | DO_OPEN_DIRS | NO_DOTS; exit(main_loop(&arg.mp, argv + optind, argc - optind)); }