4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
27 /* All Rights Reserved */
30 * University Copyright- Copyright (c) 1982, 1986, 1988
31 * The Regents of the University of California
34 * University Acknowledgment- Portions of this document are derived from
35 * software developed by the University of California, Berkeley, and its
39 #pragma ident "%Z%%M% %I% %E% SMI"
42 * Turn quota on/off for a filesystem.
44 #include <sys/param.h>
45 #include <sys/types.h>
47 #include <sys/mntent.h>
49 #define bcopy(f, t, n) memcpy(t, f, n)
50 #define bzero(s, n) memset(s, 0, n)
51 #define bcmp(s, d, n) memcmp(s, d, n)
53 #define index(s, r) strchr(s, r)
54 #define rindex(s, r) strrchr(s, r)
62 #include <sys/fs/ufs_quota.h>
64 #include <sys/mnttab.h>
66 #include <sys/vfstab.h>
68 int vflag
; /* verbose */
69 int aflag
; /* all file systems */
71 #define QFNAME "quotas"
74 char *mntopt(), *hasvfsopt(), *hasmntopt();
77 static void fixmntent();
78 static void mnterror();
79 static void usage(char *);
81 static int quotaonoff();
82 static int quotactl(int, char *, uid_t
, caddr_t
);
88 main(int argc
, char **argv
)
94 FILE *mtab
, *vfstab
, *tmp
;
98 char *tmpname
= "/etc/mnttab.temp";
104 whoami
= (char *)rindex(*argv
, '/') + 1;
105 if (whoami
== (char *)1)
107 if (strcmp(whoami
, "quotaoff") == 0)
109 else if (strcmp(whoami
, "quotaon") != 0) {
110 fprintf(stderr
, "Name must be quotaon or quotaoff not %s\n",
114 if ((listbuf
= (char **)malloc(sizeof (char *) * CHUNK
)) == NULL
) {
115 fprintf(stderr
, "Can't alloc lisbuf array.");
119 while ((opt
= getopt(argc
, argv
, "avV")) != EOF
) {
130 case 'V': /* Print command line */
135 (void) fprintf(stdout
, "%s -F UFS ", whoami
);
136 for (opt_cnt
= 1; opt_cnt
< argc
; opt_cnt
++) {
137 opt_text
= argv
[opt_cnt
];
139 (void) fprintf(stdout
, " %s ",
142 (void) fprintf(stdout
, "\n");
150 if (argc
<= optind
&& !aflag
) {
154 * If aflag go through vfstab and make a list of appropriate
162 vfstab
= fopen(VFSTAB
, "r");
163 if (vfstab
== NULL
) {
164 fprintf(stderr
, "Can't open %s\n", VFSTAB
);
169 while ((status
= getvfsent(vfstab
, &vfsbuf
)) == NULL
) {
170 if (strcmp(vfsbuf
.vfs_fstype
, MNTTYPE_UFS
) != 0 ||
171 (vfsbuf
.vfs_mntopts
== 0) ||
172 hasvfsopt(&vfsbuf
, MNTOPT_RO
) ||
173 (!hasvfsopt(&vfsbuf
, MNTOPT_RQ
) &&
174 !hasvfsopt(&vfsbuf
, MNTOPT_QUOTA
)))
176 *listp
= malloc(strlen(vfsbuf
.vfs_special
) + 1);
177 strcpy(*listp
, vfsbuf
.vfs_special
);
180 /* grow listbuf if needed */
181 if (listcnt
>= listmax
) {
183 listbuf
= (char **)realloc(listbuf
,
184 sizeof (char *) * listmax
);
185 if (listbuf
== NULL
) {
187 "Can't grow listbuf.\n");
190 listp
= &listbuf
[listcnt
];
197 listp
= &argv
[optind
];
198 listcnt
= argc
- optind
;
204 mtab
= fopen(MNTTAB
, "r");
206 fprintf(stderr
, "Can't open %s\n", MNTTAB
);
210 /* check every entry for validity before we change mnttab */
211 while ((status
= getmntent(mtab
, &mntp
)) == 0)
217 signal(SIGHUP
, SIG_IGN
);
218 signal(SIGQUIT
, SIG_IGN
);
219 signal(SIGINT
, SIG_IGN
);
222 * Loop through mnttab, if a file system gets turned on or off
225 while ((status
= getmntent(mtab
, &mntp
)) == NULL
) {
226 if (strcmp(mntp
.mnt_fstype
, MNTTYPE_UFS
) == 0 &&
227 !hasmntopt(&mntp
, MNTOPT_RO
) &&
228 (oneof(mntp
.mnt_special
, listp
, listcnt
) ||
229 oneof(mntp
.mnt_mountp
, listp
, listcnt
))) {
230 errs
+= quotaonoff(&mntp
, offmode
);
237 fprintf(stderr
, "Cannot do %s\n", *listp
);
248 quotaonoff(struct mnttab
*mntp
, int offmode
)
252 if (quotactl(Q_QUOTAOFF
, mntp
->mnt_mountp
, (uid_t
)0, NULL
) < 0)
255 printf("%s: quotas turned off\n", mntp
->mnt_mountp
);
257 if (quotactl(Q_QUOTAON
, mntp
->mnt_mountp
, (uid_t
)0, NULL
) <
261 printf("%s: quotas turned on\n", mntp
->mnt_mountp
);
265 fprintf(stderr
, "quotactl: ");
266 perror(mntp
->mnt_special
);
271 oneof(char *target
, char **olistp
, int on
)
274 char **listp
= olistp
;
277 if (*listp
&& strcmp(target
, *listp
) == 0) {
290 fprintf(stderr
, "ufs usage:\n");
291 fprintf(stderr
, "\t%s [-v] -a\n", whoami
);
292 fprintf(stderr
, "\t%s [-v] filesys ...\n", whoami
);
298 quotactl(int cmd
, char *mountpt
, uid_t uid
, caddr_t addr
)
302 struct quotctl quota
;
303 char qfile
[MAXPATHLEN
];
305 if (mountpt
== NULL
|| mountpt
[0] == '\0') {
309 if ((strlcpy(qfile
, mountpt
, sizeof (qfile
)) >= sizeof (qfile
)) ||
310 (strlcat(qfile
, "/" QFNAME
, sizeof (qfile
)) >= sizeof (qfile
))) {
314 if ((fd
= open64(qfile
, O_RDWR
)) < 0) {
315 fprintf(stderr
, "quotactl: %s ", qfile
);
323 status
= ioctl(fd
, Q_QUOTACTL
, "a
);
329 hasvfsopt(struct vfstab
*vfs
, char *opt
)
332 static char *tmpopts
;
335 tmpopts
= (char *)calloc(256, sizeof (char));
339 strcpy(tmpopts
, vfs
->vfs_mntopts
);
342 for (; *f
; f
= mntopt(&opts
)) {
343 if (strncmp(opt
, f
, strlen(opt
)) == 0)
344 return (f
- tmpopts
+ vfs
->vfs_mntopts
);
354 fprintf(stderr
, "%s: line in mnttab exceeds %d characters\n",
355 whoami
, MNT_LINE_MAX
-2);
358 fprintf(stderr
, "%s: line in mnttab has too few entries\n",
362 fprintf(stderr
, "%s: line in mnttab has too many entries\n",