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