Annotation of src/usr.bin/ipcs/ipcs.c, Revision 1.10
1.10 ! deraadt 1: /* $OpenBSD: ipcs.c,v 1.9 1999/08/16 16:58:22 millert Exp $ */
1.3 deraadt 2: /* $NetBSD: ipcs.c,v 1.10.6.1 1996/06/07 01:53:47 thorpej Exp $ */
1.1 deraadt 3:
4: /*
5: * Copyright (c) 1994 SigmaSoft, Th. Lockert <tholo@sigmasoft.com>
6: * All rights reserved.
7: *
8: * Redistribution and use in source and binary forms, with or without
9: * modification, are permitted provided that the following conditions
10: * are met:
11: * 1. Redistributions of source code must retain the above copyright
12: * notice, this list of conditions and the following disclaimer.
13: * 2. Redistributions in binary form must reproduce the above copyright
14: * notice, this list of conditions and the following disclaimer in the
15: * documentation and/or other materials provided with the distribution.
16: * 3. All advertising materials mentioning features or use of this software
17: * must display the following acknowledgement:
18: * This product includes software developed by SigmaSoft, Th. Lockert.
19: * 4. The name of the author may not be used to endorse or promote products
20: * derived from this software without specific prior written permission.
21: *
22: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
23: * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
24: * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
25: * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
26: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
27: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
28: * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29: * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
30: * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
31: * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32: */
33:
34: #include <sys/types.h>
35: #include <sys/param.h>
1.3 deraadt 36: #include <sys/time.h>
1.1 deraadt 37: #include <sys/proc.h>
38: #define _KERNEL
39: #include <sys/ipc.h>
40: #include <sys/sem.h>
41: #include <sys/shm.h>
42: #include <sys/msg.h>
1.3 deraadt 43: #undef _KERNEL
44:
45: #include <err.h>
46: #include <fcntl.h>
47: #include <kvm.h>
48: #include <limits.h>
49: #include <nlist.h>
50: #include <paths.h>
51: #include <stdio.h>
52: #include <stdlib.h>
53: #include <string.h>
54: #include <unistd.h>
1.1 deraadt 55:
56: void usage __P((void));
57:
1.3 deraadt 58: extern char *__progname; /* from crt0.o */
59:
1.1 deraadt 60: static struct nlist symbols[] = {
61: {"_sema"},
62: #define X_SEMA 0
63: {"_seminfo"},
64: #define X_SEMINFO 1
65: {"_semu"},
66: #define X_SEMU 2
67: {"_msginfo"},
68: #define X_MSGINFO 3
69: {"_msqids"},
70: #define X_MSQIDS 4
71: {"_shminfo"},
72: #define X_SHMINFO 5
73: {"_shmsegs"},
74: #define X_SHMSEGS 6
75: {NULL}
76: };
77:
78: static kvm_t *kd;
79:
80: char *
81: fmt_perm(mode)
82: u_short mode;
83: {
84: static char buffer[100];
85:
86: buffer[0] = '-';
87: buffer[1] = '-';
88: buffer[2] = ((mode & 0400) ? 'r' : '-');
89: buffer[3] = ((mode & 0200) ? 'w' : '-');
90: buffer[4] = ((mode & 0100) ? 'a' : '-');
91: buffer[5] = ((mode & 0040) ? 'r' : '-');
92: buffer[6] = ((mode & 0020) ? 'w' : '-');
93: buffer[7] = ((mode & 0010) ? 'a' : '-');
94: buffer[8] = ((mode & 0004) ? 'r' : '-');
95: buffer[9] = ((mode & 0002) ? 'w' : '-');
96: buffer[10] = ((mode & 0001) ? 'a' : '-');
97: buffer[11] = '\0';
98: return (&buffer[0]);
99: }
100:
101: void
102: cvt_time(t, buf)
103: time_t t;
104: char *buf;
105: {
106: struct tm *tm;
107:
108: if (t == 0) {
109: strcpy(buf, "no-entry");
110: } else {
111: tm = localtime(&t);
112: sprintf(buf, "%2d:%02d:%02d",
113: tm->tm_hour, tm->tm_min, tm->tm_sec);
114: }
115: }
116: #define SHMINFO 1
117: #define SHMTOTAL 2
118: #define MSGINFO 4
119: #define MSGTOTAL 8
120: #define SEMINFO 16
121: #define SEMTOTAL 32
122:
123: #define BIGGEST 1
124: #define CREATOR 2
125: #define OUTSTANDING 4
126: #define PID 8
127: #define TIME 16
128:
129: int
130: main(argc, argv)
131: int argc;
132: char *argv[];
133: {
134: int display = SHMINFO | MSGINFO | SEMINFO;
135: int option = 0;
136: char *core = NULL, *namelist = NULL;
1.3 deraadt 137: char errbuf[_POSIX2_LINE_MAX];
1.1 deraadt 138: int i;
139:
1.7 millert 140: while ((i = getopt(argc, argv, "MmQqSsabC:cN:optT")) != -1)
1.1 deraadt 141: switch (i) {
142: case 'M':
143: display = SHMTOTAL;
144: break;
145: case 'm':
146: display = SHMINFO;
147: break;
148: case 'Q':
149: display = MSGTOTAL;
150: break;
151: case 'q':
152: display = MSGINFO;
153: break;
154: case 'S':
155: display = SEMTOTAL;
156: break;
157: case 's':
158: display = SEMINFO;
159: break;
160: case 'T':
161: display = SHMTOTAL | MSGTOTAL | SEMTOTAL;
162: break;
163: case 'a':
164: option |= BIGGEST | CREATOR | OUTSTANDING | PID | TIME;
165: break;
166: case 'b':
167: option |= BIGGEST;
168: break;
169: case 'C':
170: core = optarg;
171: break;
172: case 'c':
173: option |= CREATOR;
174: break;
175: case 'N':
176: namelist = optarg;
177: break;
178: case 'o':
179: option |= OUTSTANDING;
180: break;
181: case 'p':
182: option |= PID;
183: break;
184: case 't':
185: option |= TIME;
186: break;
187: default:
188: usage();
189: }
1.2 deraadt 190: /*
191: * Discard setgid privileges if not the running kernel so that bad
192: * guys can't print interesting stuff from kernel memory.
193: */
1.6 tholo 194: if (namelist != NULL || core != NULL) {
195: setegid(getgid());
1.2 deraadt 196: setgid(getgid());
1.6 tholo 197: }
1.1 deraadt 198: if ((kd = kvm_open(namelist, core, NULL, O_RDONLY, "ipcs")) == NULL)
199: exit(1);
1.8 deraadt 200:
201: setegid(getgid());
202: setgid(getgid());
1.1 deraadt 203:
204: switch (kvm_nlist(kd, symbols)) {
205: case 0:
206: break;
207: case -1:
208: errx(1, "unable to read kernel symbol table.");
209: default:
210: #ifdef notdef /* they'll be told more civilly later */
211: warnx("nlist failed");
212: for (i = 0; symbols[i].n_name != NULL; i++)
213: if (symbols[i].n_value == 0)
214: warnx("symbol %s not found",
215: symbols[i].n_name);
216: break;
217: #endif
218: }
219:
220: if ((display & (MSGINFO | MSGTOTAL)) &&
1.3 deraadt 221: (kvm_read(kd, symbols[X_MSGINFO].n_value,
222: &msginfo, sizeof(msginfo)) == sizeof(msginfo))) {
1.1 deraadt 223:
224: if (display & MSGTOTAL) {
225: printf("msginfo:\n");
226: printf("\tmsgmax: %6d\t(max characters in a message)\n",
227: msginfo.msgmax);
228: printf("\tmsgmni: %6d\t(# of message queues)\n",
229: msginfo.msgmni);
230: printf("\tmsgmnb: %6d\t(max characters in a message queue)\n",
231: msginfo.msgmnb);
232: printf("\tmsgtql: %6d\t(max # of messages in system)\n",
233: msginfo.msgtql);
234: printf("\tmsgssz: %6d\t(size of a message segment)\n",
235: msginfo.msgssz);
236: printf("\tmsgseg: %6d\t(# of message segments in system)\n\n",
237: msginfo.msgseg);
238: }
239: if (display & MSGINFO) {
240: struct msqid_ds *xmsqids;
241:
1.3 deraadt 242: if (kvm_read(kd, symbols[X_MSQIDS].n_value,
243: &msqids, sizeof(msqids)) != sizeof(msqids))
244: errx(1, "kvm_read (%s): %s",
245: symbols[X_MSQIDS].n_name, kvm_geterr(kd));
246:
247: xmsqids = malloc(sizeof(struct msqid_ds) *
248: msginfo.msgmni);
249:
250: if (kvm_read(kd, (u_long)msqids, xmsqids,
251: sizeof(struct msqid_ds) * msginfo.msgmni) !=
252: sizeof(struct msqid_ds) * msginfo.msgmni)
253: errx(1, "kvm_read (msqids): %s",
254: kvm_geterr(kd));
1.1 deraadt 255:
256: printf("Message Queues:\n");
257: printf("T ID KEY MODE OWNER GROUP");
258: if (option & CREATOR)
259: printf(" CREATOR CGROUP");
260: if (option & OUTSTANDING)
261: printf(" CBYTES QNUM");
262: if (option & BIGGEST)
263: printf(" QBYTES");
264: if (option & PID)
265: printf(" LSPID LRPID");
266: if (option & TIME)
267: printf(" STIME RTIME CTIME");
268: printf("\n");
269: for (i = 0; i < msginfo.msgmni; i += 1) {
270: if (xmsqids[i].msg_qbytes != 0) {
271: char stime_buf[100], rtime_buf[100],
272: ctime_buf[100];
273: struct msqid_ds *msqptr = &xmsqids[i];
274:
275: cvt_time(msqptr->msg_stime, stime_buf);
276: cvt_time(msqptr->msg_rtime, rtime_buf);
277: cvt_time(msqptr->msg_ctime, ctime_buf);
278:
279: printf("q %6d %10d %s %8s %8s",
280: IXSEQ_TO_IPCID(i, msqptr->msg_perm),
281: msqptr->msg_perm.key,
282: fmt_perm(msqptr->msg_perm.mode),
283: user_from_uid(msqptr->msg_perm.uid, 0),
284: group_from_gid(msqptr->msg_perm.gid, 0));
285:
286: if (option & CREATOR)
287: printf(" %8s %8s",
288: user_from_uid(msqptr->msg_perm.cuid, 0),
289: group_from_gid(msqptr->msg_perm.cgid, 0));
290:
291: if (option & OUTSTANDING)
292: printf(" %6d %6d",
293: msqptr->msg_cbytes,
294: msqptr->msg_qnum);
295:
296: if (option & BIGGEST)
297: printf(" %6d",
298: msqptr->msg_qbytes);
299:
300: if (option & PID)
301: printf(" %6d %6d",
302: msqptr->msg_lspid,
303: msqptr->msg_lrpid);
304:
305: if (option & TIME)
306: printf("%s %s %s",
307: stime_buf,
308: rtime_buf,
309: ctime_buf);
310:
311: printf("\n");
312: }
313: }
314: printf("\n");
315: }
316: } else
317: if (display & (MSGINFO | MSGTOTAL)) {
318: fprintf(stderr,
319: "SVID messages facility not configured in the system\n");
320: }
321: if ((display & (SHMINFO | SHMTOTAL)) &&
1.3 deraadt 322: (kvm_read(kd, symbols[X_SHMINFO].n_value, &shminfo,
323: sizeof(shminfo)) == sizeof(shminfo))) {
324:
1.1 deraadt 325: if (display & SHMTOTAL) {
326: printf("shminfo:\n");
327: printf("\tshmmax: %7d\t(max shared memory segment size)\n",
328: shminfo.shmmax);
329: printf("\tshmmin: %7d\t(min shared memory segment size)\n",
330: shminfo.shmmin);
331: printf("\tshmmni: %7d\t(max number of shared memory identifiers)\n",
332: shminfo.shmmni);
333: printf("\tshmseg: %7d\t(max shared memory segments per process)\n",
334: shminfo.shmseg);
335: printf("\tshmall: %7d\t(max amount of shared memory in pages)\n\n",
336: shminfo.shmall);
337: }
338: if (display & SHMINFO) {
339: struct shmid_ds *xshmids;
340:
1.3 deraadt 341: if (kvm_read(kd, symbols[X_SHMSEGS].n_value, &shmsegs,
342: sizeof(shmsegs)) != sizeof(shmsegs))
343: errx(1, "kvm_read (%s): %s",
344: symbols[X_SHMSEGS].n_name, kvm_geterr(kd));
345:
346: xshmids = malloc(sizeof(struct shmid_ds) *
1.5 deraadt 347: shminfo.shmmni);
1.3 deraadt 348:
349: if (kvm_read(kd, (u_long)shmsegs, xshmids,
350: sizeof(struct shmid_ds) * shminfo.shmmni) !=
351: sizeof(struct shmid_ds) * shminfo.shmmni)
352: errx(1, "kvm_read (shmsegs): %s",
353: kvm_geterr(kd));
1.1 deraadt 354:
355: printf("Shared Memory:\n");
356: printf("T ID KEY MODE OWNER GROUP");
357: if (option & CREATOR)
358: printf(" CREATOR CGROUP");
359: if (option & OUTSTANDING)
360: printf(" NATTCH");
361: if (option & BIGGEST)
362: printf(" SEGSZ");
363: if (option & PID)
364: printf(" CPID LPID");
365: if (option & TIME)
366: printf(" ATIME DTIME CTIME");
367: printf("\n");
368: for (i = 0; i < shminfo.shmmni; i += 1) {
369: if (xshmids[i].shm_perm.mode & 0x0800) {
370: char atime_buf[100], dtime_buf[100],
371: ctime_buf[100];
372: struct shmid_ds *shmptr = &xshmids[i];
373:
374: cvt_time(shmptr->shm_atime, atime_buf);
375: cvt_time(shmptr->shm_dtime, dtime_buf);
376: cvt_time(shmptr->shm_ctime, ctime_buf);
377:
378: printf("m %6d %10d %s %8s %8s",
379: IXSEQ_TO_IPCID(i, shmptr->shm_perm),
380: shmptr->shm_perm.key,
381: fmt_perm(shmptr->shm_perm.mode),
382: user_from_uid(shmptr->shm_perm.uid, 0),
383: group_from_gid(shmptr->shm_perm.gid, 0));
384:
385: if (option & CREATOR)
386: printf(" %8s %8s",
387: user_from_uid(shmptr->shm_perm.cuid, 0),
388: group_from_gid(shmptr->shm_perm.cgid, 0));
389:
390: if (option & OUTSTANDING)
391: printf(" %6d",
392: shmptr->shm_nattch);
393:
394: if (option & BIGGEST)
395: printf(" %6d",
396: shmptr->shm_segsz);
397:
398: if (option & PID)
399: printf(" %6d %6d",
400: shmptr->shm_cpid,
401: shmptr->shm_lpid);
402:
403: if (option & TIME)
404: printf("%s %s %s",
405: atime_buf,
406: dtime_buf,
407: ctime_buf);
408:
409: printf("\n");
410: }
411: }
412: printf("\n");
413: }
414: } else
415: if (display & (SHMINFO | SHMTOTAL)) {
416: fprintf(stderr,
417: "SVID shared memory facility not configured in the system\n");
418: }
419: if ((display & (SEMINFO | SEMTOTAL)) &&
1.3 deraadt 420: (kvm_read(kd, symbols[X_SEMINFO].n_value, &seminfo,
421: sizeof(seminfo)) == sizeof(seminfo))) {
1.1 deraadt 422: struct semid_ds *xsema;
423:
424: if (display & SEMTOTAL) {
425: printf("seminfo:\n");
426: printf("\tsemmap: %6d\t(# of entries in semaphore map)\n",
427: seminfo.semmap);
428: printf("\tsemmni: %6d\t(# of semaphore identifiers)\n",
429: seminfo.semmni);
430: printf("\tsemmns: %6d\t(# of semaphores in system)\n",
431: seminfo.semmns);
432: printf("\tsemmnu: %6d\t(# of undo structures in system)\n",
433: seminfo.semmnu);
434: printf("\tsemmsl: %6d\t(max # of semaphores per id)\n",
435: seminfo.semmsl);
436: printf("\tsemopm: %6d\t(max # of operations per semop call)\n",
437: seminfo.semopm);
438: printf("\tsemume: %6d\t(max # of undo entries per process)\n",
439: seminfo.semume);
440: printf("\tsemusz: %6d\t(size in bytes of undo structure)\n",
441: seminfo.semusz);
442: printf("\tsemvmx: %6d\t(semaphore maximum value)\n",
443: seminfo.semvmx);
444: printf("\tsemaem: %6d\t(adjust on exit max value)\n\n",
445: seminfo.semaem);
446: }
447: if (display & SEMINFO) {
1.3 deraadt 448: if (kvm_read(kd, symbols[X_SEMA].n_value, &sema,
449: sizeof(sema)) != sizeof(sema))
450: errx(1, "kvm_read (%s): %s",
451: symbols[X_SEMA].n_name, kvm_geterr(kd));
452:
453: xsema = malloc(sizeof(struct semid_ds) *
454: seminfo.semmni);
455:
456: if (kvm_read(kd, (u_long)sema, xsema,
457: sizeof(struct semid_ds) * seminfo.semmni) !=
458: sizeof(struct semid_ds) * seminfo.semmni)
459: errx(1, "kvm_read (sema): %s",
460: kvm_geterr(kd));
1.1 deraadt 461:
462: printf("Semaphores:\n");
463: printf("T ID KEY MODE OWNER GROUP");
464: if (option & CREATOR)
465: printf(" CREATOR CGROUP");
466: if (option & BIGGEST)
467: printf(" NSEMS");
468: if (option & TIME)
469: printf(" OTIME CTIME");
470: printf("\n");
471: for (i = 0; i < seminfo.semmni; i += 1) {
472: if ((xsema[i].sem_perm.mode & SEM_ALLOC) != 0) {
473: char ctime_buf[100], otime_buf[100];
474: struct semid_ds *semaptr = &xsema[i];
475: int j, value;
476:
477: cvt_time(semaptr->sem_otime, otime_buf);
478: cvt_time(semaptr->sem_ctime, ctime_buf);
479:
480: printf("s %6d %10d %s %8s %8s",
481: IXSEQ_TO_IPCID(i, semaptr->sem_perm),
482: semaptr->sem_perm.key,
483: fmt_perm(semaptr->sem_perm.mode),
484: user_from_uid(semaptr->sem_perm.uid, 0),
485: group_from_gid(semaptr->sem_perm.gid, 0));
486:
487: if (option & CREATOR)
488: printf(" %8s %8s",
489: user_from_uid(semaptr->sem_perm.cuid, 0),
490: group_from_gid(semaptr->sem_perm.cgid, 0));
491:
492: if (option & BIGGEST)
493: printf(" %6d",
494: semaptr->sem_nsems);
495:
496: if (option & TIME)
497: printf("%s %s",
498: otime_buf,
499: ctime_buf);
500:
501: printf("\n");
502: }
503: }
504:
505: printf("\n");
506: }
507: } else
508: if (display & (SEMINFO | SEMTOTAL)) {
509: fprintf(stderr, "SVID semaphores facility not configured in the system\n");
510: }
511: kvm_close(kd);
512:
513: exit(0);
514: }
515:
516: void
517: usage()
518: {
519:
520: fprintf(stderr,
1.3 deraadt 521: "usage: %s [-abcmopqst] [-C corefile] [-N namelist]\n",
522: __progname);
1.1 deraadt 523: exit(1);
524: }