/******************************************************************************
* This file is Copyright 1993 by Philip G. Richards. All Rights Reserved.
* See the file README that came with this distribution for permissions on
* code usage, copying, and distribution. It comes with absolutely no warranty.
* email: <pgr@prg.ox.ac.uk>
******************************************************************************/
/* ---INFOBEGIN--- * DO NOT DELETE THIS COMMENT BLOCK!!!
COMMAND du remote "calculate the remote disk usage"
* ---INFOEND--- */
#include "client.h"
#include <stdlib.h>
#include "table.h"
static int recursive;
static int want_all, want_summary;
static unsigned int cwdlen;
static char *abscwd;
static u_long grand_total, filcnt;
#define DUBLOCKSIZE 1024
static u_int
block_convert(u_int size)
{
return (size + DUBLOCKSIZE - 1) / DUBLOCKSIZE;
}
static char *
strip_cwd(char *name, int type, int *rel)
{
if (strncmp(abscwd, name, cwdlen) == 0)
{
/* it's probably a relative pathname... */
*rel = 1;
if (type == 1 && name[cwdlen] == 0)
return "";
if (name[cwdlen] == '/')
return name + cwdlen;
/* oh well, maybe not... */
}
*rel = 0;
if (name[0] == '/' && name[1] == 0)
return "";
return name;
}
static int
add_file_size(char *name, struct stat *sbufp, int depth)
{
if (want_all || depth == 0)
{
char *sname;
int rel;
sname = strip_cwd(name, 0, &rel);
ffprintf(STDOUT, "%-7d %s%s\n", block_convert(sbufp->st_size),
rel? ".": "", sname);
}
grand_total += sbufp->st_size;
return 0;
}
static int
enter_dir(char *name, int depth, char **pdata)
{
int *curtotal;
/*
** there is no point trying to process this directory if it can't be
** read -- check the directory for readability
*/
if (!validate_operation(name, LITERAL_DIR | UTIL_DIR))
return -1;
/*
** set up some private data space to hold the current file total on
** entry to a directory; this is needed so we can print the total when
** the directory is left
*/
curtotal = (int *)malloc(sizeof(int));
*curtotal = grand_total;
*pdata = (char *)curtotal;
return 0;
}
static void
leave_dir(char *name, int depth, char *data)
{
if (!want_summary || depth == 0)
{
char *sname;
int rel;
sname = strip_cwd(name, 1, &rel);
ffprintf(STDOUT, "%-7d %s%s/\n",
block_convert(grand_total - *((int *)data)),
rel? ".": "", sname);
}
/* data will be free()'d by util_process_file() */
}
static int
do_du(char *name)
{
if (!validate_operation(name, UTIL_PROCESS_FILE))
return -1;
filcnt++;
return util_process_file(name, recursive, 0, add_file_size,
enter_dir, leave_dir);
}
/* ARGSUSED */
int
rdu_main(int argc, char *const*argv, char **envp)
{
int retval, errcnt, ch;
static char *here[2] = { ".", 0 };
int want_total;
char **argvec;
recursive = 0;
want_all = 0;
want_total = 0;
want_summary = 0;
optind = 0;
opterr = 0;
errcnt = 0;
#ifdef HAVE_OPTRESET
optreset = 1;
optind = 1;
#endif
/* options in the style of GNU du ... well, sort of */
while ((ch = getopt(argc, argv, "acrs")) != EOF)
switch (ch)
{
case 'a':
want_all = 1;
break;
case 'c':
want_total = 1;
break;
case 'r':
recursive = MAXRECURSION;
break;
case 's':
want_summary = 1;
break;
default:
errcnt++;
break;
}
if (errcnt > 0)
ffprintf(STDERR, "?du usage: du [-[acrs]] [files...]\n");
/* cross validate options */
if (want_summary && want_all)
{
ffprintf(STDERR, "?du: cannot both summarize and show all entries\n");
errcnt = 1;
}
/* if any errors in the options, return an error */
if (errcnt > 0)
return 1;
filcnt = 0;
grand_total = 0;
/* special case `du' without arguments -- becomes `du .' */
argvec = (optind == argc)? here: argv + optind;
/*
** if there is only one argument and no recursion has been requested,
** then allow it to be a directory and we will set recursive to be 1
*/
if (recursive == 0 && optind >= argc - 1)
recursive = 1;
abscwd = util_abs_path(env_dir);
cwdlen = strlen(abscwd);
/* special case "/" */
if (cwdlen == 1)
cwdlen = 0;
retval = -util_process_arglist(argvec, do_du);
(void)free(abscwd);
if (want_total && filcnt > 1)
{
ffprintf(STDOUT, "--------:------\n");
ffprintf(STDOUT, "%-7d TOTAL\n", block_convert(grand_total));
}
client_done();
return retval;
}
syntax highlighted by Code2HTML, v. 0.9.1