1 /* $OpenBSD: ipcs.c,v 1.27 2019/06/28 13:35:01 deraadt Exp $ */ 2 /* $NetBSD: ipcs.c,v 1.25 2000/06/16 03:58:20 simonb Exp $ */ 3 4 /*- 5 * Copyright (c) 2000 The NetBSD Foundation, Inc. 6 * All rights reserved. 7 * 8 * This code is derived from software contributed to The NetBSD Foundation 9 * by Simon Burge. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 * POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 /* 34 * Copyright (c) 1994 SigmaSoft, Th. Lockert <tholo@sigmasoft.com> 35 * All rights reserved. 36 * 37 * Redistribution and use in source and binary forms, with or without 38 * modification, are permitted provided that the following conditions 39 * are met: 40 * 1. Redistributions of source code must retain the above copyright 41 * notice, this list of conditions and the following disclaimer. 42 * 2. Redistributions in binary form must reproduce the above copyright 43 * notice, this list of conditions and the following disclaimer in the 44 * documentation and/or other materials provided with the distribution. 45 * 46 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 47 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 48 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 49 * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 50 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 51 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 52 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 53 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 54 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 55 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 56 */ 57 58 #include <sys/types.h> 59 #include <sys/sysctl.h> 60 #define _KERNEL /* XXX */ 61 #include <sys/ipc.h> 62 #include <sys/sem.h> 63 #include <sys/shm.h> 64 #include <sys/msg.h> 65 #undef _KERNEL 66 67 #include <err.h> 68 #include <fcntl.h> 69 #include <grp.h> 70 #include <kvm.h> 71 #include <limits.h> 72 #include <nlist.h> 73 #include <paths.h> 74 #include <pwd.h> 75 #include <stdio.h> 76 #include <stdlib.h> 77 #include <string.h> 78 #include <time.h> 79 #include <unistd.h> 80 81 void cvt_time(time_t, char *, size_t); 82 char *fmt_perm(mode_t); 83 void ipcs_kvm(void); 84 int main(int, char **); 85 void msg_sysctl(void); 86 void sem_sysctl(void); 87 void shm_sysctl(void); 88 void show_msginfo(time_t, time_t, time_t, int, key_t, mode_t, uid_t, 89 gid_t, uid_t, gid_t, u_long, u_long, u_long, pid_t, pid_t); 90 void show_msginfo_hdr(void); 91 void show_msgtotal(struct msginfo *); 92 void show_seminfo_hdr(void); 93 void show_seminfo(time_t, time_t, int, key_t, mode_t, uid_t, gid_t, 94 uid_t, gid_t, int16_t); 95 void show_semtotal(struct seminfo *); 96 void show_shminfo(time_t, time_t, time_t, int, key_t, mode_t, uid_t, 97 gid_t, uid_t, gid_t, u_int32_t, int, pid_t, pid_t); 98 void show_shminfo_hdr(void); 99 void show_shmtotal(struct shminfo *); 100 __dead void usage(void); 101 102 char * 103 fmt_perm(mode_t mode) 104 { 105 static char buffer[12]; 106 107 buffer[0] = '-'; 108 buffer[1] = '-'; 109 buffer[2] = ((mode & 0400) ? 'r' : '-'); 110 buffer[3] = ((mode & 0200) ? 'w' : '-'); 111 buffer[4] = ((mode & 0100) ? 'a' : '-'); 112 buffer[5] = ((mode & 0040) ? 'r' : '-'); 113 buffer[6] = ((mode & 0020) ? 'w' : '-'); 114 buffer[7] = ((mode & 0010) ? 'a' : '-'); 115 buffer[8] = ((mode & 0004) ? 'r' : '-'); 116 buffer[9] = ((mode & 0002) ? 'w' : '-'); 117 buffer[10] = ((mode & 0001) ? 'a' : '-'); 118 buffer[11] = '\0'; 119 return (&buffer[0]); 120 } 121 122 void 123 cvt_time(time_t t, char *buf, size_t buflen) 124 { 125 struct tm *tm; 126 127 if (t == 0) 128 (void)strlcpy(buf, "no-entry", buflen); 129 else { 130 tm = localtime(&t); 131 (void)snprintf(buf, buflen, "%2d:%02d:%02d", 132 tm->tm_hour, tm->tm_min, tm->tm_sec); 133 } 134 } 135 #define SHMINFO 1 136 #define SHMTOTAL 2 137 #define MSGINFO 4 138 #define MSGTOTAL 8 139 #define SEMINFO 16 140 #define SEMTOTAL 32 141 142 #define BIGGEST 1 143 #define CREATOR 2 144 #define OUTSTANDING 4 145 #define PID 8 146 #define TIME 16 147 148 char *core = NULL, *namelist = NULL; 149 int display = SHMINFO | MSGINFO | SEMINFO; 150 int option = 0; 151 152 int 153 main(int argc, char **argv) 154 { 155 int ch; 156 157 while ((ch = getopt(argc, argv, "MmQqSsabC:cN:optT")) != -1) 158 switch (ch) { 159 case 'M': 160 display = SHMTOTAL; 161 break; 162 case 'm': 163 display = SHMINFO; 164 break; 165 case 'Q': 166 display = MSGTOTAL; 167 break; 168 case 'q': 169 display = MSGINFO; 170 break; 171 case 'S': 172 display = SEMTOTAL; 173 break; 174 case 's': 175 display = SEMINFO; 176 break; 177 case 'T': 178 display = SHMTOTAL | MSGTOTAL | SEMTOTAL; 179 break; 180 case 'a': 181 option |= BIGGEST | CREATOR | OUTSTANDING | PID | TIME; 182 break; 183 case 'b': 184 option |= BIGGEST; 185 break; 186 case 'C': 187 core = optarg; 188 break; 189 case 'c': 190 option |= CREATOR; 191 break; 192 case 'N': 193 namelist = optarg; 194 break; 195 case 'o': 196 option |= OUTSTANDING; 197 break; 198 case 'p': 199 option |= PID; 200 break; 201 case 't': 202 option |= TIME; 203 break; 204 default: 205 usage(); 206 } 207 208 if (argc - optind > 0) 209 usage(); 210 211 if (namelist == NULL && core == NULL) { 212 if (display & (MSGINFO | MSGTOTAL)) 213 msg_sysctl(); 214 if (display & (SHMINFO | SHMTOTAL)) 215 shm_sysctl(); 216 if (display & (SEMINFO | SEMTOTAL)) 217 sem_sysctl(); 218 } else 219 ipcs_kvm(); 220 221 exit(0); 222 } 223 224 void 225 show_msgtotal(struct msginfo *msginfo) 226 { 227 228 printf("msginfo:\n"); 229 printf("\tmsgmax: %6d\t(max characters in a message)\n", 230 msginfo->msgmax); 231 printf("\tmsgmni: %6d\t(# of message queues)\n", 232 msginfo->msgmni); 233 printf("\tmsgmnb: %6d\t(max characters in a message queue)\n", 234 msginfo->msgmnb); 235 printf("\tmsgtql: %6d\t(max # of messages in system)\n", 236 msginfo->msgtql); 237 printf("\tmsgssz: %6d\t(size of a message segment)\n", 238 msginfo->msgssz); 239 printf("\tmsgseg: %6d\t(# of message segments in system)\n\n", 240 msginfo->msgseg); 241 } 242 243 void 244 show_shmtotal(struct shminfo *shminfo) 245 { 246 247 printf("shminfo:\n"); 248 printf("\tshmmax: %7d\t(max shared memory segment size)\n", 249 shminfo->shmmax); 250 printf("\tshmmin: %7d\t(min shared memory segment size)\n", 251 shminfo->shmmin); 252 printf("\tshmmni: %7d\t(max number of shared memory identifiers)\n", 253 shminfo->shmmni); 254 printf("\tshmseg: %7d\t(max shared memory segments per process)\n", 255 shminfo->shmseg); 256 printf("\tshmall: %7d\t(max amount of shared memory in pages)\n\n", 257 shminfo->shmall); 258 } 259 260 void 261 show_semtotal(struct seminfo *seminfo) 262 { 263 264 printf("seminfo:\n"); 265 printf("\tsemmni: %6d\t(# of semaphore identifiers)\n", 266 seminfo->semmni); 267 printf("\tsemmns: %6d\t(# of semaphores in system)\n", 268 seminfo->semmns); 269 printf("\tsemmnu: %6d\t(# of undo structures in system)\n", 270 seminfo->semmnu); 271 printf("\tsemmsl: %6d\t(max # of semaphores per id)\n", 272 seminfo->semmsl); 273 printf("\tsemopm: %6d\t(max # of operations per semop call)\n", 274 seminfo->semopm); 275 printf("\tsemume: %6d\t(max # of undo entries per process)\n", 276 seminfo->semume); 277 printf("\tsemusz: %6d\t(size in bytes of undo structure)\n", 278 seminfo->semusz); 279 printf("\tsemvmx: %6d\t(semaphore maximum value)\n", 280 seminfo->semvmx); 281 printf("\tsemaem: %6d\t(adjust on exit max value)\n\n", 282 seminfo->semaem); 283 } 284 285 void 286 show_msginfo_hdr(void) 287 { 288 289 printf("Message Queues:\n"); 290 printf("T ID KEY MODE OWNER GROUP"); 291 if (option & CREATOR) 292 printf(" CREATOR CGROUP"); 293 if (option & OUTSTANDING) 294 printf(" CBYTES QNUM"); 295 if (option & BIGGEST) 296 printf(" QBYTES"); 297 if (option & PID) 298 printf(" LSPID LRPID"); 299 if (option & TIME) 300 printf(" STIME RTIME CTIME"); 301 printf("\n"); 302 } 303 304 void 305 show_msginfo(time_t stime, time_t rtime, time_t ctime, int ipcid, key_t key, 306 mode_t mode, uid_t uid, gid_t gid, uid_t cuid, gid_t cgid, 307 u_long cbytes, u_long qnum, u_long qbytes, pid_t lspid, 308 pid_t lrpid) 309 { 310 char stime_buf[100], rtime_buf[100], ctime_buf[100]; 311 312 if (option & TIME) { 313 cvt_time(stime, stime_buf, sizeof(stime_buf)); 314 cvt_time(rtime, rtime_buf, sizeof(rtime_buf)); 315 cvt_time(ctime, ctime_buf, sizeof(ctime_buf)); 316 } 317 318 printf("q %8d %10ld %s %8s %8s", ipcid, key, fmt_perm(mode), 319 user_from_uid(uid, 0), group_from_gid(gid, 0)); 320 321 if (option & CREATOR) 322 printf(" %8s %8s", user_from_uid(cuid, 0), 323 group_from_gid(cgid, 0)); 324 325 if (option & OUTSTANDING) 326 printf(" %6lu %5lu", cbytes, qnum); 327 328 if (option & BIGGEST) 329 printf(" %6lu", qbytes); 330 331 if (option & PID) 332 printf(" %5ld %5ld", (long)lspid, (long)lrpid); 333 334 if (option & TIME) 335 printf(" %s %s %s", stime_buf, rtime_buf, ctime_buf); 336 337 printf("\n"); 338 } 339 340 void 341 show_shminfo_hdr(void) 342 { 343 344 printf("Shared Memory:\n"); 345 printf("T ID KEY MODE OWNER GROUP"); 346 if (option & CREATOR) 347 printf(" CREATOR CGROUP"); 348 if (option & OUTSTANDING) 349 printf(" NATTCH"); 350 if (option & BIGGEST) 351 printf(" SEGSZ"); 352 if (option & PID) 353 printf(" CPID LPID"); 354 if (option & TIME) 355 printf(" ATIME DTIME CTIME"); 356 printf("\n"); 357 } 358 359 void 360 show_shminfo(time_t atime, time_t dtime, time_t ctime, int ipcid, key_t key, 361 mode_t mode, uid_t uid, gid_t gid, uid_t cuid, gid_t cgid, 362 u_int32_t nattch, int segsz, pid_t cpid, pid_t lpid) 363 { 364 char atime_buf[100], dtime_buf[100], ctime_buf[100]; 365 366 if (option & TIME) { 367 cvt_time(atime, atime_buf, sizeof(atime_buf)); 368 cvt_time(dtime, dtime_buf, sizeof(dtime_buf)); 369 cvt_time(ctime, ctime_buf, sizeof(ctime_buf)); 370 } 371 372 printf("m %8d %10ld %s %8s %8s", ipcid, key, fmt_perm(mode), 373 user_from_uid(uid, 0), group_from_gid(gid, 0)); 374 375 if (option & CREATOR) 376 printf(" %8s %8s", user_from_uid(cuid, 0), 377 group_from_gid(cgid, 0)); 378 379 if (option & OUTSTANDING) 380 printf(" %6d", nattch); 381 382 if (option & BIGGEST) 383 printf(" %7d", segsz); 384 385 if (option & PID) 386 printf(" %5d %5d", cpid, lpid); 387 388 if (option & TIME) 389 printf(" %s %s %s", 390 atime_buf, 391 dtime_buf, 392 ctime_buf); 393 394 printf("\n"); 395 } 396 397 void 398 show_seminfo_hdr(void) 399 { 400 401 printf("Semaphores:\n"); 402 printf("T ID KEY MODE OWNER GROUP"); 403 if (option & CREATOR) 404 printf(" CREATOR CGROUP"); 405 if (option & BIGGEST) 406 printf(" NSEMS"); 407 if (option & TIME) 408 printf(" OTIME CTIME"); 409 printf("\n"); 410 } 411 412 void 413 show_seminfo(time_t otime, time_t ctime, int ipcid, key_t key, mode_t mode, 414 uid_t uid, gid_t gid, uid_t cuid, gid_t cgid, int16_t nsems) 415 { 416 char ctime_buf[100], otime_buf[100]; 417 418 if (option & TIME) { 419 cvt_time(otime, otime_buf, sizeof(otime_buf)); 420 cvt_time(ctime, ctime_buf, sizeof(ctime_buf)); 421 } 422 423 printf("s %8d %10ld %s %8s %8s", ipcid, key, fmt_perm(mode), 424 user_from_uid(uid, 0), group_from_gid(gid, 0)); 425 426 if (option & CREATOR) 427 printf(" %8s %8s", user_from_uid(cuid, 0), 428 group_from_gid(cgid, 0)); 429 430 if (option & BIGGEST) 431 printf(" %5d", nsems); 432 433 if (option & TIME) 434 printf(" %s %s", otime_buf, ctime_buf); 435 436 printf("\n"); 437 } 438 439 void 440 msg_sysctl(void) 441 { 442 struct msg_sysctl_info *msgsi; 443 char *buf; 444 int mib[3]; 445 size_t len; 446 int i, valid; 447 448 mib[0] = CTL_KERN; 449 mib[1] = KERN_SYSVMSG; 450 len = sizeof(valid); 451 if (sysctl(mib, 2, &valid, &len, NULL, 0) == -1) { 452 warn("sysctl(KERN_SYSVMSG)"); 453 return; 454 } 455 if (!valid) { 456 warnx("SVID messages facility not configured in the system"); 457 return; 458 } 459 460 mib[0] = CTL_KERN; 461 mib[1] = KERN_SYSVIPC_INFO; 462 mib[2] = KERN_SYSVIPC_MSG_INFO; 463 464 if (!(display & MSGINFO)) { 465 /* totals only */ 466 len = sizeof(struct msginfo); 467 } else { 468 if (sysctl(mib, 3, NULL, &len, NULL, 0) == -1) { 469 warn("sysctl(KERN_SYSVIPC_MSG_INFO)"); 470 return; 471 } 472 } 473 474 if ((buf = malloc(len)) == NULL) 475 err(1, "malloc"); 476 msgsi = (struct msg_sysctl_info *)buf; 477 if (sysctl(mib, 3, msgsi, &len, NULL, 0) == -1) { 478 warn("sysctl(KERN_SYSVIPC_MSG_INFO)"); 479 return; 480 } 481 482 if (display & MSGTOTAL) 483 show_msgtotal(&msgsi->msginfo); 484 485 if (display & MSGINFO) { 486 show_msginfo_hdr(); 487 for (i = 0; i < msgsi->msginfo.msgmni; i++) { 488 struct msqid_ds *msqptr = &msgsi->msgids[i]; 489 if (msqptr->msg_qbytes != 0) 490 show_msginfo(msqptr->msg_stime, 491 msqptr->msg_rtime, 492 msqptr->msg_ctime, 493 IXSEQ_TO_IPCID(i, msqptr->msg_perm), 494 msqptr->msg_perm.key, 495 msqptr->msg_perm.mode, 496 msqptr->msg_perm.uid, 497 msqptr->msg_perm.gid, 498 msqptr->msg_perm.cuid, 499 msqptr->msg_perm.cgid, 500 msqptr->msg_cbytes, 501 msqptr->msg_qnum, 502 msqptr->msg_qbytes, 503 msqptr->msg_lspid, 504 msqptr->msg_lrpid); 505 } 506 printf("\n"); 507 } 508 } 509 510 void 511 shm_sysctl(void) 512 { 513 struct shm_sysctl_info *shmsi; 514 char *buf; 515 int mib[3]; 516 size_t len; 517 int i, valid; 518 519 mib[0] = CTL_KERN; 520 mib[1] = KERN_SYSVSHM; 521 len = sizeof(valid); 522 if (sysctl(mib, 2, &valid, &len, NULL, 0) == -1) { 523 warn("sysctl(KERN_SYSVSHM)"); 524 return; 525 } 526 if (!valid) { 527 warnx("SVID shared memory facility not configured in " 528 "the system"); 529 return; 530 } 531 532 mib[0] = CTL_KERN; 533 mib[1] = KERN_SYSVIPC_INFO; 534 mib[2] = KERN_SYSVIPC_SHM_INFO; 535 536 if (!(display & SHMINFO)) { 537 /* totals only */ 538 len = sizeof(struct shminfo); 539 } else { 540 if (sysctl(mib, 3, NULL, &len, NULL, 0) == -1) { 541 warn("sysctl(KERN_SYSVIPC_SHM_INFO)"); 542 return; 543 } 544 } 545 546 if ((buf = malloc(len)) == NULL) 547 err(1, "malloc"); 548 shmsi = (struct shm_sysctl_info *)buf; 549 if (sysctl(mib, 3, shmsi, &len, NULL, 0) == -1) { 550 warn("sysctl(KERN_SYSVIPC_SHM_INFO)"); 551 return; 552 } 553 554 if (display & SHMTOTAL) 555 show_shmtotal(&shmsi->shminfo); 556 557 if (display & SHMINFO) { 558 show_shminfo_hdr(); 559 for (i = 0; i < shmsi->shminfo.shmmni; i++) { 560 struct shmid_ds *shmptr = &shmsi->shmids[i]; 561 if (shmptr->shm_internal) 562 show_shminfo(shmptr->shm_atime, 563 shmptr->shm_dtime, 564 shmptr->shm_ctime, 565 IXSEQ_TO_IPCID(i, shmptr->shm_perm), 566 shmptr->shm_perm.key, 567 shmptr->shm_perm.mode, 568 shmptr->shm_perm.uid, 569 shmptr->shm_perm.gid, 570 shmptr->shm_perm.cuid, 571 shmptr->shm_perm.cgid, 572 shmptr->shm_nattch, 573 shmptr->shm_segsz, 574 shmptr->shm_cpid, 575 shmptr->shm_lpid); 576 } 577 printf("\n"); 578 } 579 } 580 581 void 582 sem_sysctl(void) 583 { 584 struct sem_sysctl_info *semsi; 585 char *buf; 586 int mib[3]; 587 size_t len; 588 int i, valid; 589 590 mib[0] = CTL_KERN; 591 mib[1] = KERN_SYSVSEM; 592 len = sizeof(valid); 593 if (sysctl(mib, 2, &valid, &len, NULL, 0) == -1) { 594 warn("sysctl(KERN_SYSVSEM)"); 595 return; 596 } 597 if (!valid) { 598 warnx("SVID shared memory facility not configured in " 599 "the system"); 600 return; 601 } 602 603 mib[0] = CTL_KERN; 604 mib[1] = KERN_SYSVIPC_INFO; 605 mib[2] = KERN_SYSVIPC_SEM_INFO; 606 607 if (!(display & SEMINFO)) { 608 /* totals only */ 609 len = sizeof(struct seminfo); 610 } else { 611 if (sysctl(mib, 3, NULL, &len, NULL, 0) == -1) { 612 warn("sysctl(KERN_SYSVIPC_SEM_INFO)"); 613 return; 614 } 615 } 616 617 if ((buf = malloc(len)) == NULL) 618 err(1, "malloc"); 619 semsi = (struct sem_sysctl_info *)buf; 620 if (sysctl(mib, 3, semsi, &len, NULL, 0) == -1) { 621 warn("sysctl(KERN_SYSVIPC_SEM_INFO)"); 622 return; 623 } 624 625 if (display & SEMTOTAL) 626 show_semtotal(&semsi->seminfo); 627 628 if (display & SEMINFO) { 629 show_seminfo_hdr(); 630 for (i = 0; i < semsi->seminfo.semmni; i++) { 631 struct semid_ds *semaptr = &semsi->semids[i]; 632 633 if (semaptr->sem_base != NULL) 634 show_seminfo(semaptr->sem_otime, 635 semaptr->sem_ctime, 636 IXSEQ_TO_IPCID(i, semaptr->sem_perm), 637 semaptr->sem_perm.key, 638 semaptr->sem_perm.mode, 639 semaptr->sem_perm.uid, 640 semaptr->sem_perm.gid, 641 semaptr->sem_perm.cuid, 642 semaptr->sem_perm.cgid, 643 semaptr->sem_nsems); 644 } 645 printf("\n"); 646 } 647 } 648 649 void 650 ipcs_kvm(void) 651 { 652 struct msginfo msginfo; 653 struct que msgque; 654 struct msqid_ds *msqids; 655 struct seminfo seminfo; 656 struct semid_ds sem, **sema; 657 struct shminfo shminfo; 658 struct shmid_ds shmseg, **shmsegs; 659 char errbuf[_POSIX2_LINE_MAX]; 660 u_long addr; 661 kvm_t *kd; 662 int i; 663 struct nlist symbols[] = { 664 {"_sema"}, 665 #define X_SEMA 0 666 {"_seminfo"}, 667 #define X_SEMINFO 1 668 {"_semu"}, 669 #define X_SEMU 2 670 {"_msginfo"}, 671 #define X_MSGINFO 3 672 {"_msg_queues"}, 673 #define X_MSG_QUEUES 4 674 {"_shminfo"}, 675 #define X_SHMINFO 5 676 {"_shmsegs"}, 677 #define X_SHMSEGS 6 678 {NULL} 679 }; 680 681 if ((kd = kvm_openfiles(namelist, core, NULL, O_RDONLY, 682 errbuf)) == NULL) 683 errx(1, "can't open kvm: %s", errbuf); 684 685 switch (kvm_nlist(kd, symbols)) { 686 case 0: 687 break; 688 case -1: 689 errx(1, "%s: unable to read symbol table.", 690 namelist == NULL ? _PATH_UNIX : namelist); 691 /* NOTREACHED */ 692 default: 693 #ifdef notdef /* they'll be told more civilly later */ 694 warnx("nlist failed"); 695 for (i = 0; symbols[i].n_name != NULL; i++) 696 if (symbols[i].n_value == 0) 697 warnx("symbol %s not found", symbols[i].n_name); 698 #endif 699 break; 700 } 701 702 if ((display & (MSGINFO | MSGTOTAL)) && 703 (kvm_read(kd, symbols[X_MSGINFO].n_value, 704 &msginfo, sizeof(msginfo)) == sizeof(msginfo))) { 705 706 if (display & MSGTOTAL) 707 show_msgtotal(&msginfo); 708 709 if (display & MSGINFO) { 710 if (kvm_read(kd, symbols[X_MSG_QUEUES].n_value, 711 &addr, sizeof(addr)) != sizeof(addr)) 712 errx(1, "kvm_read (%s): %s", 713 symbols[X_MSG_QUEUES].n_name, 714 kvm_geterr(kd)); 715 716 msqids = calloc(sizeof(struct msqid_ds), 717 msginfo.msgmni); 718 if (msqids == NULL) 719 err(1, "calloc"); 720 721 /* walk the TAILQ */ 722 while (addr != 0) { 723 if (kvm_read(kd, addr, &msgque, sizeof(msgque)) 724 != sizeof(msgque)) 725 errx(1, "kvm_read (%s): %s", 726 "msg que", kvm_geterr(kd)); 727 msqids[msgque.que_ix] = msgque.msqid_ds; 728 addr = (u_long)TAILQ_NEXT(&msgque, que_next); 729 } 730 731 show_msginfo_hdr(); 732 for (i = 0; i < msginfo.msgmni; i++) { 733 struct msqid_ds *msqptr = &msqids[i]; 734 if (msqptr->msg_qbytes != 0) 735 show_msginfo(msqptr->msg_stime, 736 msqptr->msg_rtime, 737 msqptr->msg_ctime, 738 IXSEQ_TO_IPCID(i, msqptr->msg_perm), 739 msqptr->msg_perm.key, 740 msqptr->msg_perm.mode, 741 msqptr->msg_perm.uid, 742 msqptr->msg_perm.gid, 743 msqptr->msg_perm.cuid, 744 msqptr->msg_perm.cgid, 745 msqptr->msg_cbytes, 746 msqptr->msg_qnum, 747 msqptr->msg_qbytes, 748 msqptr->msg_lspid, 749 msqptr->msg_lrpid); 750 } 751 printf("\n"); 752 } 753 } else { 754 if (display & (MSGINFO | MSGTOTAL)) { 755 warnx("SVID messages facility not configured in " 756 "the system"); 757 } 758 } 759 if ((display & (SHMINFO | SHMTOTAL)) && 760 (kvm_read(kd, symbols[X_SHMINFO].n_value, &shminfo, 761 sizeof(shminfo)) == sizeof(shminfo))) { 762 763 if (display & SHMTOTAL) 764 show_shmtotal(&shminfo); 765 766 if (display & SHMINFO) { 767 if (kvm_read(kd, symbols[X_SHMSEGS].n_value, &addr, 768 sizeof(addr)) != sizeof(addr)) 769 errx(1, "kvm_read (%s): %s", 770 symbols[X_SHMSEGS].n_name, kvm_geterr(kd)); 771 772 shmsegs = calloc(sizeof(struct shmid_ds *), 773 shminfo.shmmni); 774 if (shmsegs == NULL) 775 err(1, "calloc"); 776 777 if (kvm_read(kd, addr, shmsegs, 778 sizeof(struct shmid_ds *) * shminfo.shmmni) != 779 sizeof(struct shmid_ds *) * shminfo.shmmni) 780 errx(1, "kvm_read (shmsegs): %s", 781 kvm_geterr(kd)); 782 783 show_shminfo_hdr(); 784 for (i = 0; i < shminfo.shmmni; i++) { 785 if (shmsegs[i] == NULL) 786 continue; 787 788 if (kvm_read(kd, (u_long)shmsegs[i], &shmseg, 789 sizeof(shmseg)) != sizeof(shmseg)) 790 errx(1, "kvm_read (shmseg): %s", 791 kvm_geterr(kd)); 792 show_shminfo(shmseg.shm_atime, 793 shmseg.shm_dtime, 794 shmseg.shm_ctime, 795 IXSEQ_TO_IPCID(i, shmseg.shm_perm), 796 shmseg.shm_perm.key, 797 shmseg.shm_perm.mode, 798 shmseg.shm_perm.uid, 799 shmseg.shm_perm.gid, 800 shmseg.shm_perm.cuid, 801 shmseg.shm_perm.cgid, 802 shmseg.shm_nattch, 803 shmseg.shm_segsz, 804 shmseg.shm_cpid, 805 shmseg.shm_lpid); 806 } 807 printf("\n"); 808 } 809 } else 810 if (display & (SHMINFO | SHMTOTAL)) { 811 warnx("SVID shared memory facility not configured in " 812 "the system"); 813 } 814 if ((display & (SEMINFO | SEMTOTAL)) && 815 (kvm_read(kd, symbols[X_SEMINFO].n_value, &seminfo, 816 sizeof(seminfo)) == sizeof(seminfo))) { 817 if (display & SEMTOTAL) 818 show_semtotal(&seminfo); 819 820 if (display & SEMINFO) { 821 if (kvm_read(kd, symbols[X_SEMA].n_value, &addr, 822 sizeof(addr)) != sizeof(addr)) 823 errx(1, "kvm_read (%s): %s", 824 symbols[X_SEMA].n_name, kvm_geterr(kd)); 825 826 sema = calloc(sizeof(struct semid_ds *), 827 seminfo.semmni); 828 if (sema == NULL) 829 err(1, "calloc"); 830 831 if (kvm_read(kd, addr, sema, 832 sizeof(struct semid_ds *) * seminfo.semmni) != 833 sizeof(struct semid_ds *) * seminfo.semmni) 834 errx(1, "kvm_read (sema): %s", 835 kvm_geterr(kd)); 836 837 show_seminfo_hdr(); 838 for (i = 0; i < seminfo.semmni; i++) { 839 if (sema[i] == NULL) 840 continue; 841 842 if (kvm_read(kd, (u_long)sema[i], &sem, 843 sizeof(sem)) != sizeof(sem)) 844 errx(1, "kvm_read (sem): %s", 845 kvm_geterr(kd)); 846 show_seminfo(sem.sem_otime, 847 sem.sem_ctime, 848 IXSEQ_TO_IPCID(i, sem.sem_perm), 849 sem.sem_perm.key, 850 sem.sem_perm.mode, 851 sem.sem_perm.uid, 852 sem.sem_perm.gid, 853 sem.sem_perm.cuid, 854 sem.sem_perm.cgid, 855 sem.sem_nsems); 856 } 857 printf("\n"); 858 } 859 } else 860 if (display & (SEMINFO | SEMTOTAL)) { 861 warnx("SVID semaphores facility not configured in " 862 "the system"); 863 } 864 kvm_close(kd); 865 } 866 867 void 868 usage(void) 869 { 870 extern char *__progname; 871 872 fprintf(stderr, 873 "usage: %s [-abcMmopQqSsTt] [-C core] [-N system]\n", 874 __progname); 875 exit(1); 876 } 877