int rresvport_addr(int *alport, struct sockaddr_storage *addr) { int res, err; (void) __priv_bracket(PRIV_ON); res = _rresvport_addr(alport, addr); err = errno; (void) __priv_bracket(PRIV_OFF); errno = err; return (res); }
int getdiskquota(struct mnttab *mntp, uid_t uid, struct dqblk *dqp) { int fd; dev_t fsdev; struct stat64 statb; char qfilename[MAXPATHLEN]; if (stat64(mntp->mnt_special, &statb) < 0 || (statb.st_mode & S_IFMT) != S_IFBLK) return (0); fsdev = statb.st_rdev; (void) snprintf(qfilename, sizeof (qfilename), "%s/%s", mntp->mnt_mountp, QFNAME); if (stat64(qfilename, &statb) < 0 || statb.st_dev != fsdev) return (0); (void) __priv_bracket(PRIV_ON); fd = open64(qfilename, O_RDONLY); (void) __priv_bracket(PRIV_OFF); if (fd < 0) return (0); (void) llseek(fd, (offset_t)dqoff(uid), L_SET); switch (read(fd, dqp, sizeof (struct dqblk))) { case 0: /* EOF */ /* * Convert implicit 0 quota (EOF) * into an explicit one (zero'ed dqblk). */ memset((caddr_t)dqp, 0, sizeof (struct dqblk)); break; case sizeof (struct dqblk): /* OK */ break; default: /* ERROR */ close(fd); return (0); } close(fd); return (1); }
int quotactl(int cmd, char *mountp, uid_t uid, caddr_t addr) { int fd; int status; struct quotctl quota; char qfile[MAXPATHLEN]; FILE *fstab; struct mnttab mnt; if ((mountp == NULL) && (cmd == Q_ALLSYNC)) { /* * 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. */ if ((fstab = fopen(MNTTAB, "r")) == NULL) { fprintf(stderr, "%s: ", MNTTAB); perror("open"); zexit(32); } fd = -1; while ((status = getmntent(fstab, &mnt)) == NULL) { if (strcmp(mnt.mnt_fstype, MNTTYPE_UFS) != 0 || hasopt(MNTOPT_RO, mnt.mnt_mntopts)) continue; if ((strlcpy(qfile, mnt.mnt_mountp, sizeof (qfile)) >= sizeof (qfile)) || (strlcat(qfile, "/" QFNAME, sizeof (qfile)) >= sizeof (qfile))) { continue; } (void) __priv_bracket(PRIV_ON); fd = open64(qfile, O_RDONLY); (void) __priv_bracket(PRIV_OFF); if (fd != -1) break; } fclose(fstab); if (fd == -1) { errno = ENOENT; return (-1); } } else { if (mountp == NULL || mountp[0] == '\0') { errno = ENOENT; return (-1); } if ((strlcpy(qfile, mountp, sizeof (qfile)) >= sizeof (qfile)) || (strlcat(qfile, "/" QFNAME, sizeof (qfile)) >= sizeof (qfile))) { errno = ENOENT; return (-1); } (void) __priv_bracket(PRIV_ON); fd = open64(qfile, O_RDONLY); (void) __priv_bracket(PRIV_OFF); if (fd < 0) return (-1); } /* else */ quota.op = cmd; quota.uid = uid; quota.addr = addr; status = ioctl(fd, Q_QUOTACTL, "a); if (fd != 0) close(fd); return (status); }
int main(int argc, char *argv[]) { struct utmpx *ut; struct utmpx *utmpbegin; struct utmpx *utmpend; struct utmpx *utp; struct uproc *up, *parent, *pgrp; struct psinfo info; struct sigaction actinfo[ACTSIZE]; struct pstatus statinfo; size_t size; struct stat sbuf; DIR *dirp; struct dirent *dp; char pname[64]; char *fname; int procfd; char *cp; int i; int days, hrs, mins; int entries; double loadavg[3]; /* * This program needs the proc_owner privilege */ (void) __init_suid_priv(PU_CLEARLIMITSET, PRIV_PROC_OWNER, (char *)NULL); (void) setlocale(LC_ALL, ""); #if !defined(TEXT_DOMAIN) #define TEXT_DOMAIN "SYS_TEST" #endif (void) textdomain(TEXT_DOMAIN); login = (argv[0][0] == '-'); cp = strrchr(argv[0], '/'); firstchar = login ? argv[0][1] : (cp == 0) ? argv[0][0] : cp[1]; prog = argv[0]; while (argc > 1) { if (argv[1][0] == '-') { for (i = 1; argv[1][i]; i++) { switch (argv[1][i]) { case 'h': header = 0; break; case 'l': lflag++; break; case 's': lflag = 0; break; case 'u': case 'w': firstchar = argv[1][i]; break; default: (void) fprintf(stderr, gettext( "%s: bad flag %s\n"), prog, argv[1]); exit(1); } } } else { if (!isalnum(argv[1][0]) || argc > 2) { (void) fprintf(stderr, gettext( "usage: %s [ -hlsuw ] [ user ]\n"), prog); exit(1); } else sel_user = argv[1]; } argc--; argv++; } /* * read the UTMPX_FILE (contains information about each logged in user) */ if (stat(UTMPX_FILE, &sbuf) == ERR) { (void) fprintf(stderr, gettext("%s: stat error of %s: %s\n"), prog, UTMPX_FILE, strerror(errno)); exit(1); } entries = sbuf.st_size / sizeof (struct futmpx); size = sizeof (struct utmpx) * entries; if ((ut = malloc(size)) == NULL) { (void) fprintf(stderr, gettext("%s: malloc error of %s: %s\n"), prog, UTMPX_FILE, strerror(errno)); exit(1); } (void) utmpxname(UTMPX_FILE); utmpbegin = ut; utmpend = (struct utmpx *)((char *)utmpbegin + size); setutxent(); while ((ut < utmpend) && ((utp = getutxent()) != NULL)) (void) memcpy(ut++, utp, sizeof (*ut)); endutxent(); (void) time(&now); /* get current time */ if (header) { /* print a header */ prtat(&now); for (ut = utmpbegin; ut < utmpend; ut++) { if (ut->ut_type == USER_PROCESS) { if (!nonuserx(*ut)) nusers++; } else if (ut->ut_type == BOOT_TIME) { uptime = now - ut->ut_xtime; uptime += 30; days = uptime / (60*60*24); uptime %= (60*60*24); hrs = uptime / (60*60); uptime %= (60*60); mins = uptime / 60; PRINTF((gettext("up"))); if (days > 0) PRINTF((gettext( " %d day(s),"), days)); if (hrs > 0 && mins > 0) { PRINTF((" %2d:%02d,", hrs, mins)); } else { if (hrs > 0) PRINTF((gettext( " %d hr(s),"), hrs)); if (mins > 0) PRINTF((gettext( " %d min(s),"), mins)); } } } ut = utmpbegin; /* rewind utmp data */ PRINTF((((nusers == 1) ? gettext(" %d user") : gettext(" %d users")), nusers)); /* * Print 1, 5, and 15 minute load averages. */ (void) getloadavg(loadavg, 3); PRINTF((gettext(", load average: %.2f, %.2f, %.2f\n"), loadavg[LOADAVG_1MIN], loadavg[LOADAVG_5MIN], loadavg[LOADAVG_15MIN])); if (firstchar == 'u') /* uptime command */ exit(0); if (lflag) { PRINTF((dcgettext(NULL, "User tty " "login@ idle JCPU PCPU what\n", LC_TIME))); } else { PRINTF((dcgettext(NULL, "User tty idle what\n", LC_TIME))); } if (fflush(stdout) == EOF) { perror((gettext("%s: fflush failed\n"), prog)); exit(1); } } /* * loop through /proc, reading info about each process * and build the parent/child tree */ if (!(dirp = opendir(PROCDIR))) { (void) fprintf(stderr, gettext("%s: could not open %s: %s\n"), prog, PROCDIR, strerror(errno)); exit(1); } while ((dp = readdir(dirp)) != NULL) { if (dp->d_name[0] == '.') continue; retry: (void) sprintf(pname, "%s/%s/", PROCDIR, dp->d_name); fname = pname + strlen(pname); (void) strcpy(fname, "psinfo"); if ((procfd = open(pname, O_RDONLY)) < 0) continue; if (read(procfd, &info, sizeof (info)) != sizeof (info)) { int err = errno; (void) close(procfd); if (err == EAGAIN) goto retry; if (err != ENOENT) (void) fprintf(stderr, gettext( "%s: read() failed on %s: %s \n"), prog, pname, strerror(err)); continue; } (void) close(procfd); up = findhash(info.pr_pid); up->p_ttyd = info.pr_ttydev; up->p_state = (info.pr_nlwp == 0? ZOMBIE : RUNNING); up->p_time = 0; up->p_ctime = 0; up->p_igintr = 0; (void) strncpy(up->p_comm, info.pr_fname, sizeof (info.pr_fname)); up->p_args[0] = 0; if (up->p_state != NONE && up->p_state != ZOMBIE) { (void) strcpy(fname, "status"); /* now we need the proc_owner privilege */ (void) __priv_bracket(PRIV_ON); procfd = open(pname, O_RDONLY); /* drop proc_owner privilege after open */ (void) __priv_bracket(PRIV_OFF); if (procfd < 0) continue; if (read(procfd, &statinfo, sizeof (statinfo)) != sizeof (statinfo)) { int err = errno; (void) close(procfd); if (err == EAGAIN) goto retry; if (err != ENOENT) (void) fprintf(stderr, gettext( "%s: read() failed on %s: %s \n"), prog, pname, strerror(err)); continue; } (void) close(procfd); up->p_time = statinfo.pr_utime.tv_sec + statinfo.pr_stime.tv_sec; /* seconds */ up->p_ctime = statinfo.pr_cutime.tv_sec + statinfo.pr_cstime.tv_sec; (void) strcpy(fname, "sigact"); /* now we need the proc_owner privilege */ (void) __priv_bracket(PRIV_ON); procfd = open(pname, O_RDONLY); /* drop proc_owner privilege after open */ (void) __priv_bracket(PRIV_OFF); if (procfd < 0) continue; if (read(procfd, actinfo, sizeof (actinfo)) != sizeof (actinfo)) { int err = errno; (void) close(procfd); if (err == EAGAIN) goto retry; if (err != ENOENT) (void) fprintf(stderr, gettext( "%s: read() failed on %s: %s \n"), prog, pname, strerror(err)); continue; } (void) close(procfd); up->p_igintr = actinfo[SIGINT-1].sa_handler == SIG_IGN && actinfo[SIGQUIT-1].sa_handler == SIG_IGN; /* * Process args. */ up->p_args[0] = 0; clnarglist(info.pr_psargs); (void) strcat(up->p_args, info.pr_psargs); if (up->p_args[0] == 0 || up->p_args[0] == '-' && up->p_args[1] <= ' ' || up->p_args[0] == '?') { (void) strcat(up->p_args, " ("); (void) strcat(up->p_args, up->p_comm); (void) strcat(up->p_args, ")"); } } /* * link pgrp together in case parents go away * Pgrp chain is a single linked list originating * from the pgrp leader to its group member. */ if (info.pr_pgid != info.pr_pid) { /* not pgrp leader */ pgrp = findhash(info.pr_pgid); up->p_pgrpl = pgrp->p_pgrpl; pgrp->p_pgrpl = up; } parent = findhash(info.pr_ppid); /* if this is the new member, link it in */ if (parent->p_upid != INITPROCESS) { if (parent->p_child) { up->p_sibling = parent->p_child; up->p_child = 0; } parent->p_child = up; } } /* revert to non-privileged user after opening */ (void) __priv_relinquish(); (void) closedir(dirp); (void) time(&now); /* get current time */ /* * loop through utmpx file, printing process info * about each logged in user */ for (ut = utmpbegin; ut < utmpend; ut++) { if (ut->ut_type != USER_PROCESS) continue; if (sel_user && strncmp(ut->ut_name, sel_user, NMAX) != 0) continue; /* we're looking for somebody else */ /* print login name of the user */ PRINTF(("%-*.*s ", LOGIN_WIDTH, NMAX, ut->ut_name)); /* print tty user is on */ if (lflag) { PRINTF(("%-*.*s ", LINE_WIDTH, LMAX, ut->ut_line)); } else { if (ut->ut_line[0] == 'p' && ut->ut_line[1] == 't' && ut->ut_line[2] == 's' && ut->ut_line[3] == '/') { PRINTF(("%-*.*s ", LINE_WIDTH, LMAX, &ut->ut_line[4])); } else { PRINTF(("%-*.*s ", LINE_WIDTH, LMAX, ut->ut_line)); } } /* print when the user logged in */ if (lflag) { time_t tim = ut->ut_xtime; prtat(&tim); } /* print idle time */ idle = findidle(ut->ut_line); prttime(idle, 8); showtotals(findhash(ut->ut_pid)); } if (fclose(stdout) == EOF) { perror((gettext("%s: fclose failed"), prog)); exit(1); } return (0); }
int ucbmain(int argc, char **argv) { psinfo_t info; /* process information structure from /proc */ char *psargs = NULL; /* pointer to buffer for -w and -ww options */ char *svpsargs = NULL; struct psent *psent; int entsize; int nent; pid_t maxpid; struct tty *ttyp = tty; char *tmp; char *p; int c; pid_t pid; /* pid: process id */ pid_t ppid; /* ppid: parent process id */ int i, found; size_t size; DIR *dirp; struct dirent *dentp; char psname[100]; char asname[100]; int pdlen; size_t len; (void) setlocale(LC_ALL, ""); my_uid = getuid(); /* * This program needs the proc_owner privilege */ (void) __init_suid_priv(PU_CLEARLIMITSET, PRIV_PROC_OWNER, (char *)NULL); /* * calculate width of pid fields based on configured MAXPID * (must be at least 5 to retain output format compatibility) */ maxpid = (pid_t)sysconf(_SC_MAXPID); pidwidth = 1; while ((maxpid /= 10) > 0) ++pidwidth; pidwidth = pidwidth < 5 ? 5 : pidwidth; if (ioctl(1, TIOCGWINSZ, &win) == -1) twidth = 80; else twidth = (win.ws_col == 0 ? 80 : win.ws_col); /* add the '-' for BSD compatibility */ if (argc > 1) { if (argv[1][0] != '-' && !isdigit(argv[1][0])) { len = strlen(argv[1]) + 2; tmp = malloc(len); if (tmp != NULL) { (void) snprintf(tmp, len, "%s%s", "-", argv[1]); argv[1] = tmp; } } } setbuf(stdout, stdbuf); while ((c = getopt(argc, argv, "lcaengrSt:xuvwU")) != EOF) switch (c) { case 'g': gflg++; /* include process group leaders */ break; case 'c': /* display internal command name */ cflg++; break; case 'r': /* restrict output to running processes */ rflg++; break; case 'S': /* display time by process and all reaped children */ Sflg++; break; case 'x': /* process w/o controlling tty */ xflg++; break; case 'l': /* long listing */ lflg++; uflg = vflg = 0; break; case 'u': /* user-oriented output */ uflg++; lflg = vflg = 0; break; case 'U': /* update private database ups_data */ Uflg++; break; case 'w': /* increase display width */ if (twidth < 132) twidth = 132; else /* second w option */ twidth = NCARGS; break; case 'v': /* display virtual memory format */ vflg++; lflg = uflg = 0; break; case 'a': /* * display all processes except process group * leaders and processes w/o controlling tty */ aflg++; gflg++; break; case 'e': /* Display environment along with aguments. */ eflg++; break; case 'n': /* Display numerical output */ nflg++; break; case 't': /* restrict output to named terminal */ #define TSZ 30 tflg++; gflg++; xflg = 0; p1 = optarg; do { /* only loop through once (NTTYS = 2) */ parg = argbuf; if (ntty >= NTTYS-1) break; getarg(); if ((p = malloc(TSZ+1)) == NULL) { (void) fprintf(stderr, "ps: no memory\n"); exit(1); } p[0] = '\0'; size = TSZ; if (isdigit(*parg)) { (void) strcpy(p, "tty"); size -= 3; } (void) strncat(p, parg, size); ttyp->tdev = PRNODEV; if (parg && *parg == '?') xflg++; else { char nambuf[TSZ+6]; /* for /dev/+\0 */ struct stat64 s; (void) strcpy(nambuf, "/dev/"); (void) strcat(nambuf, p); if (stat64(nambuf, &s) == 0) ttyp->tdev = s.st_rdev; } ttyp++->tname = p; ntty++; } while (*p1); break; default: /* error on ? */ errflg++; break; } if (errflg) usage(); if (optind + 1 < argc) { /* more than one additional argument */ (void) fprintf(stderr, "ps: too many arguments\n"); usage(); } /* * The -U option is obsolete. Attempts to use it cause ps to exit * without printing anything. */ if (Uflg) exit(0); if (optind < argc) { /* user specified a specific proc id */ pflg++; p1 = argv[optind]; parg = argbuf; getarg(); if (!num(parg)) { (void) fprintf(stderr, "ps: %s is an invalid non-numeric argument for a process id\n", parg); usage(); } pidsave = (pid_t)atol(parg); aflg = rflg = xflg = 0; gflg++; } if (tflg) ttyp->tname = NULL; /* allocate an initial guess for the number of processes */ entsize = 1024; psent = malloc(entsize * sizeof (struct psent)); if (psent == NULL) { (void) fprintf(stderr, "ps: no memory\n"); exit(1); } nent = 0; /* no active entries yet */ if (lflg) { (void) sprintf(hdr, " F UID%*s%*s %%C PRI NI SZ RSS " "WCHAN S TT TIME COMMAND", pidwidth + 1, "PID", pidwidth + 1, "PPID"); } else if (uflg) { if (nflg) (void) sprintf(hdr, " UID%*s %%CPU %%MEM SZ RSS " "TT S START TIME COMMAND", pidwidth + 1, "PID"); else (void) sprintf(hdr, "USER %*s %%CPU %%MEM SZ RSS " "TT S START TIME COMMAND", pidwidth + 1, "PID"); } else if (vflg) { (void) sprintf(hdr, "%*s TT S TIME SIZE RSS %%CPU %%MEM " "COMMAND", pidwidth + 1, "PID"); } else (void) sprintf(hdr, "%*s TT S TIME COMMAND", pidwidth + 1, "PID"); twidth = twidth - strlen(hdr) + 6; (void) printf("%s\n", hdr); if (twidth > PRARGSZ && (psargs = malloc(twidth)) == NULL) { (void) fprintf(stderr, "ps: no memory\n"); exit(1); } svpsargs = psargs; /* * Determine which processes to print info about by searching * the /proc directory and looking at each process. */ if ((dirp = opendir(procdir)) == NULL) { (void) fprintf(stderr, "ps: cannot open PROC directory %s\n", procdir); exit(1); } (void) strcpy(psname, procdir); pdlen = strlen(psname); psname[pdlen++] = '/'; /* for each active process --- */ while (dentp = readdir(dirp)) { int psfd; /* file descriptor for /proc/nnnnn/psinfo */ int asfd; /* file descriptor for /proc/nnnnn/as */ if (dentp->d_name[0] == '.') /* skip . and .. */ continue; (void) strcpy(psname + pdlen, dentp->d_name); (void) strcpy(asname, psname); (void) strcat(psname, "/psinfo"); (void) strcat(asname, "/as"); retry: if ((psfd = open(psname, O_RDONLY)) == -1) continue; asfd = -1; if (psargs != NULL || eflg) { /* now we need the proc_owner privilege */ (void) __priv_bracket(PRIV_ON); asfd = open(asname, O_RDONLY); /* drop proc_owner privilege after open */ (void) __priv_bracket(PRIV_OFF); } /* * Get the info structure for the process */ if (read(psfd, &info, sizeof (info)) != sizeof (info)) { int saverr = errno; (void) close(psfd); if (asfd > 0) (void) close(asfd); if (saverr == EAGAIN) goto retry; if (saverr != ENOENT) (void) fprintf(stderr, "ps: read() on %s: %s\n", psname, err_string(saverr)); continue; } (void) close(psfd); found = 0; if (info.pr_lwp.pr_state == 0) /* can't happen? */ goto closeit; pid = info.pr_pid; ppid = info.pr_ppid; /* Display only process from command line */ if (pflg) { /* pid in arg list */ if (pidsave == pid) found++; else goto closeit; } /* * Omit "uninteresting" processes unless 'g' option. */ if ((ppid == 1) && !(gflg)) goto closeit; /* * Omit non-running processes for 'r' option */ if (rflg && !(info.pr_lwp.pr_sname == 'O' || info.pr_lwp.pr_sname == 'R')) goto closeit; if (!found && !tflg && !aflg && info.pr_euid != my_uid) goto closeit; /* * Read the args for the -w and -ww cases */ if (asfd > 0) { if ((psargs != NULL && preadargs(asfd, &info, psargs) == -1) || (eflg && preadenvs(asfd, &info, psargs) == -1)) { int saverr = errno; (void) close(asfd); if (saverr == EAGAIN) goto retry; if (saverr != ENOENT) (void) fprintf(stderr, "ps: read() on %s: %s\n", asname, err_string(saverr)); continue; } } else { psargs = info.pr_psargs; } if (nent >= entsize) { entsize *= 2; psent = (struct psent *)realloc((char *)psent, entsize * sizeof (struct psent)); if (psent == NULL) { (void) fprintf(stderr, "ps: no memory\n"); exit(1); } } if ((psent[nent].psinfo = malloc(sizeof (psinfo_t))) == NULL) { (void) fprintf(stderr, "ps: no memory\n"); exit(1); } *psent[nent].psinfo = info; if (psargs == NULL) psent[nent].psargs = NULL; else { if ((psent[nent].psargs = malloc(strlen(psargs)+1)) == NULL) { (void) fprintf(stderr, "ps: no memory\n"); exit(1); } (void) strcpy(psent[nent].psargs, psargs); } psent[nent].found = found; nent++; closeit: if (asfd > 0) (void) close(asfd); psargs = svpsargs; } /* revert to non-privileged user */ (void) __priv_relinquish(); (void) closedir(dirp); qsort((char *)psent, nent, sizeof (psent[0]), pscompare); for (i = 0; i < nent; i++) { struct psent *pp = &psent[i]; if (prcom(pp->found, pp->psinfo, pp->psargs)) { (void) printf("\n"); retcode = 0; } } return (retcode); }