Update to 4.01.
[profile/ivi/quota.git] / quotasync.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <unistd.h>
4 #include <fcntl.h>
5 #include <string.h>
6 #include <errno.h>
7 #include <getopt.h>
8
9 #include "pot.h"
10 #include "common.h"
11 #include "quotasys.h"
12 #include "quotaio.h"
13
14 #define FL_USER 1               /* sync user quotas */
15 #define FL_GROUP 2              /* sync group quotas */
16 #define FL_ALL 4                /* sync quotas on all filesystems */
17
18 static int flags, fmt = -1;
19 static char **mnt;
20 static int mntcnt;
21 char *progname;
22
23 static void usage(void)
24 {
25         errstr(_("Utility for syncing quotas.\nUsage:\n%s [-ug] -a | mntpoint...\n\n"), progname);
26         fprintf(stderr, _("Bugs to %s\n"), MY_EMAIL);
27         exit(1);
28 }
29
30 static void parse_options(int argcnt, char **argstr)
31 {
32         int ret;
33         struct option long_opts[] = {
34                 { "user", 0, NULL, 'u' },
35                 { "group", 0, NULL, 'g' },
36                 { "all", 0, NULL, 'a' },
37                 { "version", 0, NULL, 'V' },
38                 { "help", 0, NULL, 'h' },
39                 { NULL, 0, NULL, 0 }
40         };
41
42         while ((ret = getopt_long(argcnt, argstr, "ahugV", long_opts, NULL)) != -1) {
43                 switch (ret) {
44                         case '?':
45                         case 'h':
46                                 usage();
47                         case 'V':
48                                 version();
49                                 exit(0);
50                         case 'u':
51                                 flags |= FL_USER;
52                                 break;
53                         case 'g':
54                                 flags |= FL_GROUP;
55                                 break;
56                         case 'a':
57                                 flags |= FL_ALL;
58                                 break;
59                 }
60         }
61
62         if ((flags & FL_ALL && optind != argcnt) ||
63             (!(flags & FL_ALL) && optind == argcnt)) {
64                 fputs(_("Bad number of arguments.\n"), stderr);
65                 usage();
66         }
67         if (!(flags & FL_ALL)) {
68                 mnt = argstr + optind;
69                 mntcnt = argcnt - optind;
70         }
71         if (!(flags & (FL_USER | FL_GROUP)))
72                 flags |= FL_USER;
73 }
74
75 static int sync_one(int type, char *dev)
76 {
77         int qcmd = QCMD(Q_SYNC, type);
78
79         return quotactl(qcmd, dev, 0, NULL);
80 }
81
82 static int syncquotas(int type)
83 {
84         struct quota_handle **handles, *h;
85         int i, ret = 0;
86
87         if (flags & FL_ALL) {
88                 if (sync_one(type, NULL) < 0)
89                         errstr(_("%s quota sync failed: %s\n"), _(type2name(type)),
90                                         strerror(errno));
91                 return -1;
92         }
93
94         handles = create_handle_list(mntcnt, mnt, type, fmt,
95                                      IOI_READONLY, MS_LOCALONLY | MS_NO_AUTOFS);
96
97         for (i = 0; handles[i]; i++) {
98                 h = handles[i];
99                 if (sync_one(type, h->qh_quotadev)) {
100                         errstr(_("%s quota sync failed for %s: %s\n"),
101                                 _(type2name(type)), h->qh_quotadev, strerror(errno));
102                         ret = -1;
103                 }
104         }
105         dispose_handle_list(handles);
106
107         return ret;
108 }
109
110 int main(int argc, char **argv)
111 {
112         int ret = 0;
113
114         gettexton();
115         progname = basename(argv[0]);
116
117         parse_options(argc, argv);
118         init_kernel_interface();
119
120         if (flags & FL_USER)
121                 if (syncquotas(USRQUOTA))
122                         ret = 1;
123         if (flags & FL_GROUP)
124                 if (syncquotas(GRPQUOTA))
125                         ret = 1;
126         return ret;
127 }