static void showquotas(uid_t uid, char *name) { struct mnttab mnt; FILE *mtab; struct dqblk dqblk; uid_t myuid; struct failed_srv { char *serv_name; struct failed_srv *next; }; struct failed_srv *failed_srv_list = NULL; int rc; char my_zonename[ZONENAME_MAX]; zoneid_t my_zoneid = getzoneid(); myuid = getuid(); if (uid != myuid && myuid != 0) { printf("quota: %s (uid %d): permission denied\n", name, uid); zexit(32); } memset(my_zonename, '\0', ZONENAME_MAX); getzonenamebyid(my_zoneid, my_zonename, ZONENAME_MAX); if (vflag) heading(uid, name); mtab = fopen(MNTTAB, "r"); while (getmntent(mtab, &mnt) == NULL) { if (strcmp(mnt.mnt_fstype, MNTTYPE_ZFS) == 0) { bzero(&dqblk, sizeof (dqblk)); if (getzfsquota(name, mnt.mnt_special, &dqblk)) continue; } else if (strcmp(mnt.mnt_fstype, MNTTYPE_UFS) == 0) { if (nolocalquota || (quotactl(Q_GETQUOTA, mnt.mnt_mountp, uid, &dqblk) != 0 && !(vflag && getdiskquota(&mnt, uid, &dqblk)))) continue; } else if (strcmp(mnt.mnt_fstype, MNTTYPE_NFS) == 0) { struct replica *rl; int count; char *mntopt = NULL; /* * Skip checking quotas for file systems mounted * in other zones. Zone names will be passed in * following format from hasmntopt(): * "zone=<zone-name>,<mnt options...>" */ if ((mntopt = hasmntopt(&mnt, MNTOPT_ZONE)) && (my_zonename[0] != '\0')) { mntopt += strcspn(mntopt, "=") + 1; if (strncmp(mntopt, my_zonename, strcspn(mntopt, ",")) != 0) continue; } if (hasopt(MNTOPT_NOQUOTA, mnt.mnt_mntopts)) 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. */ if (hasopt(MNTOPT_PUBLIC, mnt.mnt_mntopts)) continue; rl = parse_replica(mnt.mnt_special, &count); if (rl == NULL) { if (count < 0) fprintf(stderr, "cannot find hostname " "and/or pathname for %s\n", mnt.mnt_mountp); else fprintf(stderr, "no memory to parse " "mnttab entry for %s\n", mnt.mnt_mountp); 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) { free_replica(rl, count); 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. */ if (strcmp(rl[0].host, "nfs") == 0 && strncmp(rl[0].path, "//", 2) == 0) { free_replica(rl, count); continue; } /* * Skip getting quotas from failing servers */ if (failed_srv_list != NULL) { struct failed_srv *tmp_list; int found_failed = 0; size_t len = strlen(rl[0].host); tmp_list = failed_srv_list; do { if (strncasecmp(rl[0].host, tmp_list->serv_name, len) == 0) { found_failed = 1; break; } } while ((tmp_list = tmp_list->next) != NULL); if (found_failed) { free_replica(rl, count); continue; } } rc = getnfsquota(rl[0].host, rl[0].path, uid, &dqblk); if (rc != RPC_SUCCESS) { size_t len; struct failed_srv *tmp_srv; /* * Failed to get quota from this server. Add * this server to failed_srv_list and skip * getting quotas for other mounted filesystems * from this server. */ if (rc == RPC_TIMEDOUT || rc == RPC_CANTSEND) { len = strlen(rl[0].host); tmp_srv = (struct failed_srv *)malloc( sizeof (struct failed_srv)); tmp_srv->serv_name = (char *)malloc( len * sizeof (char) + 1); strncpy(tmp_srv->serv_name, rl[0].host, len); tmp_srv->serv_name[len] = '\0'; tmp_srv->next = failed_srv_list; failed_srv_list = tmp_srv; } free_replica(rl, count); continue; } free_replica(rl, count); } else { continue; } if (dqblk.dqb_bsoftlimit == 0 && dqblk.dqb_bhardlimit == 0 && dqblk.dqb_fsoftlimit == 0 && dqblk.dqb_fhardlimit == 0) continue; if (vflag) prquota(&mnt, &dqblk); else warn(&mnt, &dqblk); } /* * Free list of failed servers */ while (failed_srv_list != NULL) { struct failed_srv *tmp_srv = failed_srv_list; failed_srv_list = failed_srv_list->next; free(tmp_srv->serv_name); free(tmp_srv); } fclose(mtab); }
static void showquotas(uid_t uid, char *name) { struct mnttab mnt; FILE *mtab; struct dqblk dqblk; uid_t myuid; myuid = getuid(); if (uid != myuid && myuid != 0) { printf("quota: %s (uid %d): permission denied\n", name, uid); exit(32); } if (vflag) heading(uid, name); mtab = fopen(MNTTAB, "r"); while (getmntent(mtab, &mnt) == NULL) { if (strcmp(mnt.mnt_fstype, MNTTYPE_UFS) == 0) { if (nolocalquota || (quotactl(Q_GETQUOTA, mnt.mnt_mountp, uid, &dqblk) != 0 && !(vflag && getdiskquota(&mnt, uid, &dqblk)))) continue; } else if (strcmp(mnt.mnt_fstype, MNTTYPE_NFS) == 0) { struct replica *rl; int count; if (hasopt(MNTOPT_NOQUOTA, mnt.mnt_mntopts)) 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. */ if (hasopt(MNTOPT_PUBLIC, mnt.mnt_mntopts)) continue; rl = parse_replica(mnt.mnt_special, &count); if (rl == NULL) { if (count < 0) fprintf(stderr, "cannot find hostname " "and/or pathname for %s\n", mnt.mnt_mountp); else fprintf(stderr, "no memory to parse " "mnttab entry for %s\n", mnt.mnt_mountp); 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) { free_replica(rl, count); 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. */ if (strcmp(rl[0].host, "nfs") == 0 && strncmp(rl[0].path, "//", 2) == 0) { free_replica(rl, count); continue; } if (!getnfsquota(rl[0].host, rl[0].path, uid, &dqblk)) { free_replica(rl, count); continue; } free_replica(rl, count); } else { continue; } if (dqblk.dqb_bsoftlimit == 0 && dqblk.dqb_bhardlimit == 0 && dqblk.dqb_fsoftlimit == 0 && dqblk.dqb_fhardlimit == 0) continue; if (vflag) prquota(&mnt, &dqblk); else warn(&mnt, &dqblk); } fclose(mtab); }