Annotation of src/usr.bin/ipcs/ipcs.c, Revision 1.3
1.3 ! deraadt 1: /* $NetBSD: ipcs.c,v 1.10.6.1 1996/06/07 01:53:47 thorpej Exp $ */
1.1 deraadt 2:
3: /*
4: * Copyright (c) 1994 SigmaSoft, Th. Lockert <tholo@sigmasoft.com>
5: * All rights reserved.
6: *
7: * Redistribution and use in source and binary forms, with or without
8: * modification, are permitted provided that the following conditions
9: * are met:
10: * 1. Redistributions of source code must retain the above copyright
11: * notice, this list of conditions and the following disclaimer.
12: * 2. Redistributions in binary form must reproduce the above copyright
13: * notice, this list of conditions and the following disclaimer in the
14: * documentation and/or other materials provided with the distribution.
15: * 3. All advertising materials mentioning features or use of this software
16: * must display the following acknowledgement:
17: * This product includes software developed by SigmaSoft, Th. Lockert.
18: * 4. The name of the author may not be used to endorse or promote products
19: * derived from this software without specific prior written permission.
20: *
21: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
22: * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
23: * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
24: * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27: * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28: * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29: * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
30: * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31: */
32:
33: #include <sys/types.h>
34: #include <sys/param.h>
1.3 ! deraadt 35: #include <sys/time.h>
1.1 deraadt 36: #include <sys/proc.h>
37: #define _KERNEL
38: #include <sys/ipc.h>
39: #include <sys/sem.h>
40: #include <sys/shm.h>
41: #include <sys/msg.h>
1.3 ! deraadt 42: #undef _KERNEL
! 43:
! 44: #include <err.h>
! 45: #include <fcntl.h>
! 46: #include <kvm.h>
! 47: #include <limits.h>
! 48: #include <nlist.h>
! 49: #include <paths.h>
! 50: #include <stdio.h>
! 51: #include <stdlib.h>
! 52: #include <string.h>
! 53: #include <unistd.h>
1.1 deraadt 54:
1.3 ! deraadt 55: int semconfig __P((int, ...));
1.1 deraadt 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:
140: while ((i = getopt(argc, argv, "MmQqSsabC:cN:optT")) != EOF)
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: */
194: if (namelist != NULL || core != NULL)
195: setgid(getgid());
1.1 deraadt 196: if ((kd = kvm_open(namelist, core, NULL, O_RDONLY, "ipcs")) == NULL)
197: exit(1);
198:
199: switch (kvm_nlist(kd, symbols)) {
200: case 0:
201: break;
202: case -1:
203: errx(1, "unable to read kernel symbol table.");
204: default:
205: #ifdef notdef /* they'll be told more civilly later */
206: warnx("nlist failed");
207: for (i = 0; symbols[i].n_name != NULL; i++)
208: if (symbols[i].n_value == 0)
209: warnx("symbol %s not found",
210: symbols[i].n_name);
211: break;
212: #endif
213: }
214:
215: if ((display & (MSGINFO | MSGTOTAL)) &&
1.3 ! deraadt 216: (kvm_read(kd, symbols[X_MSGINFO].n_value,
! 217: &msginfo, sizeof(msginfo)) == sizeof(msginfo))) {
1.1 deraadt 218:
219: if (display & MSGTOTAL) {
220: printf("msginfo:\n");
221: printf("\tmsgmax: %6d\t(max characters in a message)\n",
222: msginfo.msgmax);
223: printf("\tmsgmni: %6d\t(# of message queues)\n",
224: msginfo.msgmni);
225: printf("\tmsgmnb: %6d\t(max characters in a message queue)\n",
226: msginfo.msgmnb);
227: printf("\tmsgtql: %6d\t(max # of messages in system)\n",
228: msginfo.msgtql);
229: printf("\tmsgssz: %6d\t(size of a message segment)\n",
230: msginfo.msgssz);
231: printf("\tmsgseg: %6d\t(# of message segments in system)\n\n",
232: msginfo.msgseg);
233: }
234: if (display & MSGINFO) {
235: struct msqid_ds *xmsqids;
236:
1.3 ! deraadt 237: if (kvm_read(kd, symbols[X_MSQIDS].n_value,
! 238: &msqids, sizeof(msqids)) != sizeof(msqids))
! 239: errx(1, "kvm_read (%s): %s",
! 240: symbols[X_MSQIDS].n_name, kvm_geterr(kd));
! 241:
! 242: xmsqids = malloc(sizeof(struct msqid_ds) *
! 243: msginfo.msgmni);
! 244:
! 245: if (kvm_read(kd, (u_long)msqids, xmsqids,
! 246: sizeof(struct msqid_ds) * msginfo.msgmni) !=
! 247: sizeof(struct msqid_ds) * msginfo.msgmni)
! 248: errx(1, "kvm_read (msqids): %s",
! 249: kvm_geterr(kd));
1.1 deraadt 250:
251: printf("Message Queues:\n");
252: printf("T ID KEY MODE OWNER GROUP");
253: if (option & CREATOR)
254: printf(" CREATOR CGROUP");
255: if (option & OUTSTANDING)
256: printf(" CBYTES QNUM");
257: if (option & BIGGEST)
258: printf(" QBYTES");
259: if (option & PID)
260: printf(" LSPID LRPID");
261: if (option & TIME)
262: printf(" STIME RTIME CTIME");
263: printf("\n");
264: for (i = 0; i < msginfo.msgmni; i += 1) {
265: if (xmsqids[i].msg_qbytes != 0) {
266: char stime_buf[100], rtime_buf[100],
267: ctime_buf[100];
268: struct msqid_ds *msqptr = &xmsqids[i];
269:
270: cvt_time(msqptr->msg_stime, stime_buf);
271: cvt_time(msqptr->msg_rtime, rtime_buf);
272: cvt_time(msqptr->msg_ctime, ctime_buf);
273:
274: printf("q %6d %10d %s %8s %8s",
275: IXSEQ_TO_IPCID(i, msqptr->msg_perm),
276: msqptr->msg_perm.key,
277: fmt_perm(msqptr->msg_perm.mode),
278: user_from_uid(msqptr->msg_perm.uid, 0),
279: group_from_gid(msqptr->msg_perm.gid, 0));
280:
281: if (option & CREATOR)
282: printf(" %8s %8s",
283: user_from_uid(msqptr->msg_perm.cuid, 0),
284: group_from_gid(msqptr->msg_perm.cgid, 0));
285:
286: if (option & OUTSTANDING)
287: printf(" %6d %6d",
288: msqptr->msg_cbytes,
289: msqptr->msg_qnum);
290:
291: if (option & BIGGEST)
292: printf(" %6d",
293: msqptr->msg_qbytes);
294:
295: if (option & PID)
296: printf(" %6d %6d",
297: msqptr->msg_lspid,
298: msqptr->msg_lrpid);
299:
300: if (option & TIME)
301: printf("%s %s %s",
302: stime_buf,
303: rtime_buf,
304: ctime_buf);
305:
306: printf("\n");
307: }
308: }
309: printf("\n");
310: }
311: } else
312: if (display & (MSGINFO | MSGTOTAL)) {
313: fprintf(stderr,
314: "SVID messages facility not configured in the system\n");
315: }
316: if ((display & (SHMINFO | SHMTOTAL)) &&
1.3 ! deraadt 317: (kvm_read(kd, symbols[X_SHMINFO].n_value, &shminfo,
! 318: sizeof(shminfo)) == sizeof(shminfo))) {
! 319:
1.1 deraadt 320: if (display & SHMTOTAL) {
321: printf("shminfo:\n");
322: printf("\tshmmax: %7d\t(max shared memory segment size)\n",
323: shminfo.shmmax);
324: printf("\tshmmin: %7d\t(min shared memory segment size)\n",
325: shminfo.shmmin);
326: printf("\tshmmni: %7d\t(max number of shared memory identifiers)\n",
327: shminfo.shmmni);
328: printf("\tshmseg: %7d\t(max shared memory segments per process)\n",
329: shminfo.shmseg);
330: printf("\tshmall: %7d\t(max amount of shared memory in pages)\n\n",
331: shminfo.shmall);
332: }
333: if (display & SHMINFO) {
334: struct shmid_ds *xshmids;
335:
1.3 ! deraadt 336: if (kvm_read(kd, symbols[X_SHMSEGS].n_value, &shmsegs,
! 337: sizeof(shmsegs)) != sizeof(shmsegs))
! 338: errx(1, "kvm_read (%s): %s",
! 339: symbols[X_SHMSEGS].n_name, kvm_geterr(kd));
! 340:
! 341: xshmids = malloc(sizeof(struct shmid_ds) *
! 342: msginfo.msgmni);
! 343:
! 344: if (kvm_read(kd, (u_long)shmsegs, xshmids,
! 345: sizeof(struct shmid_ds) * shminfo.shmmni) !=
! 346: sizeof(struct shmid_ds) * shminfo.shmmni)
! 347: errx(1, "kvm_read (shmsegs): %s",
! 348: kvm_geterr(kd));
1.1 deraadt 349:
350: printf("Shared Memory:\n");
351: printf("T ID KEY MODE OWNER GROUP");
352: if (option & CREATOR)
353: printf(" CREATOR CGROUP");
354: if (option & OUTSTANDING)
355: printf(" NATTCH");
356: if (option & BIGGEST)
357: printf(" SEGSZ");
358: if (option & PID)
359: printf(" CPID LPID");
360: if (option & TIME)
361: printf(" ATIME DTIME CTIME");
362: printf("\n");
363: for (i = 0; i < shminfo.shmmni; i += 1) {
364: if (xshmids[i].shm_perm.mode & 0x0800) {
365: char atime_buf[100], dtime_buf[100],
366: ctime_buf[100];
367: struct shmid_ds *shmptr = &xshmids[i];
368:
369: cvt_time(shmptr->shm_atime, atime_buf);
370: cvt_time(shmptr->shm_dtime, dtime_buf);
371: cvt_time(shmptr->shm_ctime, ctime_buf);
372:
373: printf("m %6d %10d %s %8s %8s",
374: IXSEQ_TO_IPCID(i, shmptr->shm_perm),
375: shmptr->shm_perm.key,
376: fmt_perm(shmptr->shm_perm.mode),
377: user_from_uid(shmptr->shm_perm.uid, 0),
378: group_from_gid(shmptr->shm_perm.gid, 0));
379:
380: if (option & CREATOR)
381: printf(" %8s %8s",
382: user_from_uid(shmptr->shm_perm.cuid, 0),
383: group_from_gid(shmptr->shm_perm.cgid, 0));
384:
385: if (option & OUTSTANDING)
386: printf(" %6d",
387: shmptr->shm_nattch);
388:
389: if (option & BIGGEST)
390: printf(" %6d",
391: shmptr->shm_segsz);
392:
393: if (option & PID)
394: printf(" %6d %6d",
395: shmptr->shm_cpid,
396: shmptr->shm_lpid);
397:
398: if (option & TIME)
399: printf("%s %s %s",
400: atime_buf,
401: dtime_buf,
402: ctime_buf);
403:
404: printf("\n");
405: }
406: }
407: printf("\n");
408: }
409: } else
410: if (display & (SHMINFO | SHMTOTAL)) {
411: fprintf(stderr,
412: "SVID shared memory facility not configured in the system\n");
413: }
414: if ((display & (SEMINFO | SEMTOTAL)) &&
1.3 ! deraadt 415: (kvm_read(kd, symbols[X_SEMINFO].n_value, &seminfo,
! 416: sizeof(seminfo)) == sizeof(seminfo))) {
1.1 deraadt 417: struct semid_ds *xsema;
418:
419: if (display & SEMTOTAL) {
420: printf("seminfo:\n");
421: printf("\tsemmap: %6d\t(# of entries in semaphore map)\n",
422: seminfo.semmap);
423: printf("\tsemmni: %6d\t(# of semaphore identifiers)\n",
424: seminfo.semmni);
425: printf("\tsemmns: %6d\t(# of semaphores in system)\n",
426: seminfo.semmns);
427: printf("\tsemmnu: %6d\t(# of undo structures in system)\n",
428: seminfo.semmnu);
429: printf("\tsemmsl: %6d\t(max # of semaphores per id)\n",
430: seminfo.semmsl);
431: printf("\tsemopm: %6d\t(max # of operations per semop call)\n",
432: seminfo.semopm);
433: printf("\tsemume: %6d\t(max # of undo entries per process)\n",
434: seminfo.semume);
435: printf("\tsemusz: %6d\t(size in bytes of undo structure)\n",
436: seminfo.semusz);
437: printf("\tsemvmx: %6d\t(semaphore maximum value)\n",
438: seminfo.semvmx);
439: printf("\tsemaem: %6d\t(adjust on exit max value)\n\n",
440: seminfo.semaem);
441: }
442: if (display & SEMINFO) {
443: if (semconfig(SEM_CONFIG_FREEZE) != 0) {
444: perror("semconfig");
445: fprintf(stderr,
446: "Can't lock semaphore facility - winging it...\n");
447: }
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: union semun junk;
477:
478: cvt_time(semaptr->sem_otime, otime_buf);
479: cvt_time(semaptr->sem_ctime, ctime_buf);
480:
481: printf("s %6d %10d %s %8s %8s",
482: IXSEQ_TO_IPCID(i, semaptr->sem_perm),
483: semaptr->sem_perm.key,
484: fmt_perm(semaptr->sem_perm.mode),
485: user_from_uid(semaptr->sem_perm.uid, 0),
486: group_from_gid(semaptr->sem_perm.gid, 0));
487:
488: if (option & CREATOR)
489: printf(" %8s %8s",
490: user_from_uid(semaptr->sem_perm.cuid, 0),
491: group_from_gid(semaptr->sem_perm.cgid, 0));
492:
493: if (option & BIGGEST)
494: printf(" %6d",
495: semaptr->sem_nsems);
496:
497: if (option & TIME)
498: printf("%s %s",
499: otime_buf,
500: ctime_buf);
501:
502: printf("\n");
503: }
504: }
505:
506: (void) semconfig(SEM_CONFIG_THAW);
507:
508: printf("\n");
509: }
510: } else
511: if (display & (SEMINFO | SEMTOTAL)) {
512: fprintf(stderr, "SVID semaphores facility not configured in the system\n");
513: }
514: kvm_close(kd);
515:
516: exit(0);
517: }
518:
519: void
520: usage()
521: {
522:
523: fprintf(stderr,
1.3 ! deraadt 524: "usage: %s [-abcmopqst] [-C corefile] [-N namelist]\n",
! 525: __progname);
1.1 deraadt 526: exit(1);
527: }