/* * Disk quota reporting program. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include enum options { ID_FL = 0x1, HELP_FL = 0x2, GET_FL = 0x4, SET_FL = 0x8, ALL_FL = 0x10, ON_FL = 0x20, OFF_FL = 0x40, TYPE_FL = 0x80, }; unsigned flags = 0; char device[128]; char path[128]; int id; int type; int warn = 0; void print_dqblk(int qid, struct if_dqblk *dqb) { printf("%6d %10lld %10lld %10lld, %10lld %10lld %10lld\n", qid, dqb->dqb_curspace, dqb->dqb_bsoftlimit, dqb->dqb_bhardlimit, dqb->dqb_curinodes, dqb->dqb_isoftlimit, dqb->dqb_ihardlimit); if (((int64_t)dqb->dqb_curspace) < 0 || ((int64_t)dqb->dqb_bsoftlimit) < 0 || ((int64_t)dqb->dqb_bhardlimit) < 0 || ((int64_t)dqb->dqb_curinodes) < 0 || ((int64_t)dqb->dqb_isoftlimit) < 0 || ((int64_t)dqb->dqb_ihardlimit) < 0 ) { printf ("WANR: Negative quota !!!"); warn = qid + 1; } } int onoff_quota(int type, int on) { int beg = type; int end = type; int i, ret; char *name[] = {"aquota.user", "aquota.group", "aquota.tree"}; char p[1024]; if (!(flags & TYPE_FL) && !(flags & ALL_FL)) { printf("Err --set with out --all or --type opt\n"); exit(1); } if (flags & ALL_FL) { beg = 0; end = 2; /* MAXQUOTAS */ } for (i = beg; i <= end; i++) { snprintf(p, sizeof(p), "%s/%s", path, name[i]); ret = quotactl(QCMD(on ? Q_QUOTAON : Q_QUOTAOFF, i), device, QFMT_VFS_V0, p); if (ret) perror("quotactl"); } return ret; } int show_quota(int start, int end) { struct if_dqblk dqb, sum_dqb; int i,found = 0; int ret; memset(&sum_dqb, 0, sizeof(sum_dqb)); printf(" ID curspace soft hard curinodes soft hard\n"); for (i = start; i < end; i++) { ret = quotactl(QCMD(Q_GETQUOTA, type),device, i, (char*)&dqb); if (ret && errno == ESRCH) continue; if (!dqb.dqb_curspace && !dqb.dqb_bsoftlimit && !dqb.dqb_bhardlimit && !dqb.dqb_curinodes && !dqb.dqb_isoftlimit && !dqb.dqb_ihardlimit) continue; if (ret) { perror ("quotactl"); return 1; } print_dqblk(i, &dqb); found++; sum_dqb.dqb_curspace += dqb.dqb_curspace; sum_dqb.dqb_curinodes += dqb.dqb_curinodes; } printf("--------------------------------------------------------------------------------\n"); print_dqblk(found, &sum_dqb); if (warn) printf("WARN!! bad quota found id:%d \n", warn - 1); return warn; } int main(int argc, char **argv) { unsigned treeid = -1; gid_t gidset[NGROUPS], *gidsetp; int i, ret; int ngroups = 0; struct if_dqblk dqb; struct option long_opts[] = { { "help", 0, NULL, 'H' }, { "path", 1, NULL, 'p'}, { "get", 0, NULL, 'G' }, { "set", 0, NULL, 'S' }, { "on", 0, NULL, 'O'}, { "off", 0, NULL, 'o'}, { "device", 1, NULL, 'D'}, { "bsoft", 1, NULL, 'b'}, { "bhard",1, NULL, 'B'}, { "curspace",1, NULL, 'c'}, { "curinodes",1, NULL, 'C'}, { "isoft",1, NULL, 'i'}, { "ihard",2, NULL, 'I'}, { "type",1, NULL, 'T'}, { "all",0, NULL, 'a'}, { "id",1, NULL, 'd'}, { NULL, 0, NULL, 0 } }; while ((ret = getopt_long(argc, argv, "HGSp:D:T:i:b:B:i:I:c:C:aOo", long_opts, NULL)) != -1) { switch (ret) { case 'H': flags |= HELP_FL; break; case 'G': flags |= GET_FL; break; case 'S': flags |= SET_FL; break; case 'O': flags |= ON_FL; break; case 'o': flags |= OFF_FL; break; case 'p': strcpy(path, optarg); break; case 'a': flags |= ALL_FL; break; case 'D' : strcpy(device ,optarg); break; case 'T' : flags |= TYPE_FL; type = atoi(optarg); break; case 'd' : id = atoi(optarg); flags |= ID_FL; break; case 'b' : dqb.dqb_bsoftlimit= atol(optarg); dqb.dqb_valid |= QIF_BLIMITS; break; case 'B' : dqb.dqb_bhardlimit= atol(optarg); dqb.dqb_valid |= QIF_BLIMITS; break; case 'i' : dqb.dqb_isoftlimit= atol(optarg); dqb.dqb_valid |= QIF_ILIMITS; break; case 'I' : dqb.dqb_ihardlimit= atol(optarg); dqb.dqb_valid |= QIF_ILIMITS; break; case 'c' : dqb.dqb_curspace= atol(optarg); dqb.dqb_valid |= QIF_SPACE; break; case 'C' : dqb.dqb_curinodes= atol(optarg); dqb.dqb_valid |= QIF_INODES; break; default: printf("Unknown opt:%c\n", ret); exit(1); } } argc -= optind; argv += optind; if (flags & (ON_FL |OFF_FL)) return onoff_quota(type, flags & ON_FL); if (flags & SET_FL) { if ((flags & (ID_FL| TYPE_FL)) != (ID_FL| TYPE_FL)) { printf("Err --set with out --id opt\n"); exit(1); } if (!(dqb.dqb_valid & QIF_ALL)) { printf("Err --set with bhard,bsoft,isoft,ihard " "curspace, curinodes opt\n"); exit(1); } ret = quotactl(QCMD(Q_SETQUOTA, type),device, id, (char*)&dqb); if (ret) { perror("quotactl"); return 1; } } if (flags & GET_FL) if (flags & ALL_FL) return show_quota(0, 65535); else return show_quota(id, id + 1); return 0; }