quota.c revision fabd6b6f69e3a926eb29b3da3cf84698a105520c
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
/* All Rights Reserved */
/*
* University Copyright- Copyright (c) 1982, 1986, 1988
* The Regents of the University of California
* All Rights Reserved
*
* University Acknowledgment- Portions of this document are derived from
* software developed by the University of California, Berkeley, and its
* contributors.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Disk quota reporting program.
*/
#include <stdio.h>
#include <ctype.h>
#include <pwd.h>
#include <errno.h>
#include <fcntl.h>
#include <memory.h>
#include <sys/sysmacros.h>
#include <priv_utils.h>
#include <locale.h>
int vflag;
int nolocalquota;
extern int optind;
extern char *optarg;
#define QFNAME "quotas"
#if DEV_BSIZE < 1024
#else
#endif
#if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */
#endif
static void showquotas(uid_t, char *);
static void fmttime(char *, long);
int
{
int opt;
int i;
int status = 0;
(void) textdomain(TEXT_DOMAIN);
/*
* PRIV_FILE_DAC_READ is needed to read the QFNAME file
* Clear all other privleges from the limit set, and add
* the required privilege to the bracketed set.
*/
NULL) == -1) {
gettext("Insufficient privileges, "
"quota must be set-uid root or have "
"file_dac_read privileges\n"));
exit(1);
}
switch (opt) {
case 'v':
vflag++;
break;
case 'V': /* Print command line */
{
char *opt_text;
int opt_count;
if (opt_text)
}
}
break;
case '?':
exit(32);
}
}
if (vflag)
nolocalquota++;
}
exit(0);
}
} else
}
return (status);
}
static void
{
if (uid == 0) {
if (vflag)
printf("no disk quota for uid 0\n");
return;
}
else
}
int
{
return (32);
}
if (vflag)
return (0);
}
return (0);
}
static void
{
exit(32);
}
if (vflag)
if (nolocalquota ||
continue;
int count;
continue;
/*
* Skip quota processing if mounted with public
* option. We are not likely to be able to pierce
* a fire wall to contact the quota server.
*/
continue;
if (count < 0)
else
"mnttab entry for %s\n",
continue;
}
/*
* We skip quota reporting on mounts with replicas
* for the following reasons:
*
* (1) Very little point in reporting quotas on
* a set of read-only replicas ... how will the
* user correct the problem?
*
* (2) Which replica would we report the quota
* for? If we pick the current replica, what
* happens when a fail over event occurs? The
* next time quota is run, the quota will look
* all different, or there won't even be one.
* This has the potential to break scripts.
*
* If we prnt quouta for all replicas, how do
* we present the output without breaking scripts?
*/
if (count > 1) {
continue;
}
/*
* Skip file systems mounted using public fh.
* We are not likely to be able to pierce
* a fire wall to contact the quota server.
*/
continue;
}
continue;
}
} else {
continue;
}
continue;
if (vflag)
else
}
}
static void
{
if (dqp->dqb_bhardlimit &&
} else if (dqp->dqb_bsoftlimit &&
if (dqp->dqb_btimelimit == 0) {
printf("Over disk quota on %s, remove %luK\n",
char btimeleft[80];
printf("Over disk quota on %s, remove %luK within %s\n",
} else {
"Over disk quota on %s, time limit has expired, remove %luK\n",
}
}
if (dqp->dqb_fhardlimit &&
} else if (dqp->dqb_fsoftlimit &&
if (dqp->dqb_ftimelimit == 0) {
printf("Over file quota on %s, remove %lu file%s\n",
"s" : ""));
char ftimeleft[80];
"Over file quota on %s, remove %lu file%s within %s\n",
} else {
"Over file quota on %s, time limit has expired, remove %lu file%s\n",
"s" : ""));
}
}
}
static void
{
printf("%-12s %7s%7s%7s%12s%7s%7s%7s%12s\n",
"Filesystem",
"usage",
"quota",
"limit",
"timeleft",
"files",
"quota",
"limit",
"timeleft");
}
static void
{
char *cp;
if (dqp->dqb_btimelimit == 0) {
} else {
}
} else {
btimeleft[0] = '\0';
}
if (dqp->dqb_ftimelimit == 0) {
} else {
}
} else {
ftimeleft[0] = '\0';
}
cp = "";
} else {
}
printf("%-12.12s %7d %6d %6d %11s %6d %6d %6d %11s\n",
cp,
}
static void
{
int i;
static struct {
int c_secs; /* conversion units in secs */
char *c_str; /* unit string */
} cunits [] = {
{60*60*24*28, "months"},
{60*60*24*7, "weeks"},
{60*60*24, "days"},
{60*60, "hours"},
{60, "mins"},
{1, "secs"}
};
if (time <= 0) {
return;
}
break;
}
}
int
alldigits(char *s)
{
int c;
c = *s++;
do {
if (!isdigit(c))
return (0);
} while (c = *s++);
return (1);
}
int
{
int fd;
char qfilename[MAXPATHLEN];
return (0);
return (0);
(void) __priv_bracket(PRIV_ON);
(void) __priv_bracket(PRIV_OFF);
if (fd < 0)
return (0);
case 0: /* EOF */
/*
* Convert implicit 0 quota (EOF)
* into an explicit one (zero'ed dqblk).
*/
break;
case sizeof (struct dqblk): /* OK */
break;
default: /* ERROR */
return (0);
}
return (1);
}
int
{
int fd;
int status;
char qfile[MAXPATHLEN];
/*
* Find the mount point of any mounted file system. This is
* because the ioctl that implements the quotactl call has
* to go to a real file, and not to the block device.
*/
perror("open");
exit(32);
}
fd = -1;
continue;
sizeof (qfile))) {
continue;
}
(void) __priv_bracket(PRIV_ON);
(void) __priv_bracket(PRIV_OFF);
if (fd != -1)
break;
}
if (fd == -1) {
return (-1);
}
} else {
return (-1);
}
(qfile)) ||
(qfile))) {
return (-1);
}
(void) __priv_bracket(PRIV_ON);
(void) __priv_bracket(PRIV_OFF);
if (fd < 0)
return (-1);
} /* else */
if (fd != 0)
return (status);
}
/*
* Return 1 if opt appears in optlist
*/
int
{
char *value;
char *opts[2];
return (0);
while (*optlist != '\0') {
return (1);
}
return (0);
}
#include <netdb.h>
static int
{
struct getquota_args gq_args;
struct getquota_rslt gq_rslt;
extern char *strchr();
return (0);
}
case Q_OK:
{
return (0);
return (1);
}
case Q_NOQUOTA:
break;
case Q_EPERM:
break;
default:
break;
}
return (0);
}
int
{
struct timeval tottimeout;
static int oldprognum, oldversnum;
/*
* Cache the client handle in case there are lots
* server. If the server returns an error, don't
* make further calls.
*/
if (cl) {
}
return ((int)RPC_TIMEDOUT);
return (RPC_CANTSEND);
}
}
if (clnt_stat != RPC_SUCCESS)
return ((int)clnt_stat); /* don't bother retrying */
tottimeout.tv_usec = 0;
return ((int)clnt_stat);
}