[net.sources] byteyears.c

geoff@desint.UUCP (Geoff Kuenning) (11/17/86)

#!/bin/sh
# There was a utility mentioned in comp.unix.questions that sounded fairly
# useful;  it reports the product of a file's size and it's age.  I decided
# it sounded handy enough to whip up.  Here's my version, complete with
# man page.  I'd be interested in hearing about differences between mine
# and the Bell version.  Make with "make byteyears" or
# "cc -O -o byteyears byteyears.c", according to taste.  There shouldn't
# be any BSD/System V dependencies (famous last words).
#
#	Geoff Kuenning
#	{hplabs,ihnp4}!trwrb!desint!geoff
#
: This is a shar archive.  Extract with sh, not csh.
: The rest of this file will extract:
:
:	 byteyears.1l byteyears.c
:
echo extracting - byteyears.1l
sed 's/^-//' > byteyears.1l << '/*EOF'
.TH BYTEYEARS 1 Local
.SH NAME
byteyears \- report size-age product for a file
.SH SYNOPSIS
.B byteyears
[
.B \-acm
]
[
.B \-d
.I n
] file[s]
.SH DESCRIPTION
.I Byteyears\^
multiplies the size of each file given by its age in years, and reports
the result on the standard output.
The age is defined as the difference between the current time and the
file's modification time.
.P
The switches can be used to modify the behavior as follows:
.IP \-a
Use the access time in computing the age.
.IP \-c
Use the inode-changed time in computing the age.
.IP \-m
Use the modification time in computing the age (default).
.IP "\-d \fIn\fP"
Print the result with
.I n
digits after the decimal point (default 0).
.SH "SEE ALSO"
.IR stat (2)
.br
.IR stat (1l),
if available at your site.
.SH RESTRICTIONS
This command is intended as an aid to users in management of their personal
directory space.
System administrators are cautioned against using this command as a basis
for accounting systems, because UNIX inode times are easily changed.
In particular, note that the sequence "touch x; byteyears x" will always
report zero (or at least a very small number).
.P
A year is considered to be 365.25 days.
/*EOF
echo extracting - byteyears.c
sed 's/^-//' > byteyears.c << '/*EOF'
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>

int		main ();		/* Report product of file sz and age */
static void	usage ();		/* Print a usage message */
static int	byteyears ();		/* Do it for one file */

enum timefield				/* Time field selection in statbuf */
    {
    ACCESS,
    CREATE,
    MODIFY
    };

#define YEAR	(365.25*86400)		/* Number of seconds in a year */
					/* (86400 is the number in a day) */

extern char *	optarg;			/* Current 'getopt' argument value */
extern int	optind;			/* Current 'getopt' option index */
extern long	time ();		/* Return system time */

int main (argc, argv)			/* Report product of file sz and age */
    register int	argc;		/* Argument count */
    register char *	argv[];		/* Argument vector */
    {
    int			digits = 0;	/* No. of significant digits to use */
    long		now;		/* The time right now */
    int			optch;		/* 'Getopt' argument character */
    int			status = 0;	/* Eventual return status */
    enum timefield	tfield = MODIFY; /* Which time field to use */

    while ((optch = getopt (argc, argv, "acmd:")) != EOF)
	{
	switch (optch)
	    {
	    case 'a':
		tfield = ACCESS;
		break;
	    case 'c':
		tfield = CREATE;
		break;
	    case 'm':
		tfield = MODIFY;
		break;
	    case 'd':
		digits = atoi (optarg);
		break;
	    default:
		usage ();
		return 2;
	    }
	}
    if (optind >= argc)
	{
	usage ();
	return 2;
	}
    now = time ((long *) NULL);
    for (  ;  optind < argc;  optind++)
	status |= byteyears (argv[optind], now, tfield, digits);
    return status;
    }

static void usage ()			/* Print a usage message */
    {
    (void) fprintf (stderr, "Usage:  byteyears -[acm] [-d n] files\n");
    }

-/* Produce report for one file */
static int byteyears (name, now, tfield, digits)
    register char *	name;		/* Name of the file to report about */
    long		now;		/* The time right now */
    enum timefield	tfield;		/* Which field to work with */
    int			digits;		/* Number of significant digits to do */
    {
    double		byears;		/* Byte-year product */
    struct stat		statbuf;	/* File status, for size and age */

    if (stat (name, &statbuf) < 0)
	{
	perror (name);
	return 1;
	}
    switch (tfield)
	{
	case ACCESS:
	    now -= statbuf.st_atime;
	    break;
	case CREATE:
	    now -= statbuf.st_ctime;
	    break;
	case MODIFY:
	    now -= statbuf.st_mtime;
	    break;
	}
    byears = (double) statbuf.st_size * (double) now / YEAR;
    (void) printf ("%s\t%.*f\n", name, digits, byears);
    return 0;
    }
/*EOF
exit
-- 

	Geoff Kuenning
	{hplabs,ihnp4}!trwrb!desint!geoff