Annotation of src/usr.bin/ipcs/ipcs.c, Revision 1.1
1.1 ! deraadt 1: /* $NetBSD: ipcs.c,v 1.10 1995/04/15 02:22:40 cgd Exp $ */
! 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 <stdio.h>
! 34: #include <stdlib.h>
! 35: #include <string.h>
! 36: #include <unistd.h>
! 37: #include <fcntl.h>
! 38: #include <paths.h>
! 39: #include <nlist.h>
! 40: #include <kvm.h>
! 41: #include <err.h>
! 42:
! 43: #include <sys/types.h>
! 44: #include <sys/param.h>
! 45: #include <sys/proc.h>
! 46: #define _KERNEL
! 47: #include <sys/ipc.h>
! 48: #include <sys/sem.h>
! 49: #include <sys/shm.h>
! 50: #include <sys/msg.h>
! 51:
! 52: int semconfig __P((int,...));
! 53: void usage __P((void));
! 54:
! 55: static struct nlist symbols[] = {
! 56: {"_sema"},
! 57: #define X_SEMA 0
! 58: {"_seminfo"},
! 59: #define X_SEMINFO 1
! 60: {"_semu"},
! 61: #define X_SEMU 2
! 62: {"_msginfo"},
! 63: #define X_MSGINFO 3
! 64: {"_msqids"},
! 65: #define X_MSQIDS 4
! 66: {"_shminfo"},
! 67: #define X_SHMINFO 5
! 68: {"_shmsegs"},
! 69: #define X_SHMSEGS 6
! 70: {NULL}
! 71: };
! 72:
! 73: static kvm_t *kd;
! 74:
! 75: char *
! 76: fmt_perm(mode)
! 77: u_short mode;
! 78: {
! 79: static char buffer[100];
! 80:
! 81: buffer[0] = '-';
! 82: buffer[1] = '-';
! 83: buffer[2] = ((mode & 0400) ? 'r' : '-');
! 84: buffer[3] = ((mode & 0200) ? 'w' : '-');
! 85: buffer[4] = ((mode & 0100) ? 'a' : '-');
! 86: buffer[5] = ((mode & 0040) ? 'r' : '-');
! 87: buffer[6] = ((mode & 0020) ? 'w' : '-');
! 88: buffer[7] = ((mode & 0010) ? 'a' : '-');
! 89: buffer[8] = ((mode & 0004) ? 'r' : '-');
! 90: buffer[9] = ((mode & 0002) ? 'w' : '-');
! 91: buffer[10] = ((mode & 0001) ? 'a' : '-');
! 92: buffer[11] = '\0';
! 93: return (&buffer[0]);
! 94: }
! 95:
! 96: void
! 97: cvt_time(t, buf)
! 98: time_t t;
! 99: char *buf;
! 100: {
! 101: struct tm *tm;
! 102:
! 103: if (t == 0) {
! 104: strcpy(buf, "no-entry");
! 105: } else {
! 106: tm = localtime(&t);
! 107: sprintf(buf, "%2d:%02d:%02d",
! 108: tm->tm_hour, tm->tm_min, tm->tm_sec);
! 109: }
! 110: }
! 111: #define SHMINFO 1
! 112: #define SHMTOTAL 2
! 113: #define MSGINFO 4
! 114: #define MSGTOTAL 8
! 115: #define SEMINFO 16
! 116: #define SEMTOTAL 32
! 117:
! 118: #define BIGGEST 1
! 119: #define CREATOR 2
! 120: #define OUTSTANDING 4
! 121: #define PID 8
! 122: #define TIME 16
! 123:
! 124: int
! 125: main(argc, argv)
! 126: int argc;
! 127: char *argv[];
! 128: {
! 129: int display = SHMINFO | MSGINFO | SEMINFO;
! 130: int option = 0;
! 131: char *core = NULL, *namelist = NULL;
! 132: int i;
! 133:
! 134: while ((i = getopt(argc, argv, "MmQqSsabC:cN:optT")) != EOF)
! 135: switch (i) {
! 136: case 'M':
! 137: display = SHMTOTAL;
! 138: break;
! 139: case 'm':
! 140: display = SHMINFO;
! 141: break;
! 142: case 'Q':
! 143: display = MSGTOTAL;
! 144: break;
! 145: case 'q':
! 146: display = MSGINFO;
! 147: break;
! 148: case 'S':
! 149: display = SEMTOTAL;
! 150: break;
! 151: case 's':
! 152: display = SEMINFO;
! 153: break;
! 154: case 'T':
! 155: display = SHMTOTAL | MSGTOTAL | SEMTOTAL;
! 156: break;
! 157: case 'a':
! 158: option |= BIGGEST | CREATOR | OUTSTANDING | PID | TIME;
! 159: break;
! 160: case 'b':
! 161: option |= BIGGEST;
! 162: break;
! 163: case 'C':
! 164: core = optarg;
! 165: break;
! 166: case 'c':
! 167: option |= CREATOR;
! 168: break;
! 169: case 'N':
! 170: namelist = optarg;
! 171: break;
! 172: case 'o':
! 173: option |= OUTSTANDING;
! 174: break;
! 175: case 'p':
! 176: option |= PID;
! 177: break;
! 178: case 't':
! 179: option |= TIME;
! 180: break;
! 181: default:
! 182: usage();
! 183: }
! 184: if ((kd = kvm_open(namelist, core, NULL, O_RDONLY, "ipcs")) == NULL)
! 185: exit(1);
! 186:
! 187: switch (kvm_nlist(kd, symbols)) {
! 188: case 0:
! 189: break;
! 190: case -1:
! 191: errx(1, "unable to read kernel symbol table.");
! 192: default:
! 193: #ifdef notdef /* they'll be told more civilly later */
! 194: warnx("nlist failed");
! 195: for (i = 0; symbols[i].n_name != NULL; i++)
! 196: if (symbols[i].n_value == 0)
! 197: warnx("symbol %s not found",
! 198: symbols[i].n_name);
! 199: break;
! 200: #endif
! 201: }
! 202:
! 203: if ((display & (MSGINFO | MSGTOTAL)) &&
! 204: kvm_read(kd, symbols[X_MSGINFO].n_value, &msginfo, sizeof(msginfo))) {
! 205:
! 206: if (display & MSGTOTAL) {
! 207: printf("msginfo:\n");
! 208: printf("\tmsgmax: %6d\t(max characters in a message)\n",
! 209: msginfo.msgmax);
! 210: printf("\tmsgmni: %6d\t(# of message queues)\n",
! 211: msginfo.msgmni);
! 212: printf("\tmsgmnb: %6d\t(max characters in a message queue)\n",
! 213: msginfo.msgmnb);
! 214: printf("\tmsgtql: %6d\t(max # of messages in system)\n",
! 215: msginfo.msgtql);
! 216: printf("\tmsgssz: %6d\t(size of a message segment)\n",
! 217: msginfo.msgssz);
! 218: printf("\tmsgseg: %6d\t(# of message segments in system)\n\n",
! 219: msginfo.msgseg);
! 220: }
! 221: if (display & MSGINFO) {
! 222: struct msqid_ds *xmsqids;
! 223:
! 224: kvm_read(kd, symbols[X_MSQIDS].n_value, &msqids, sizeof(msqids));
! 225: xmsqids = malloc(sizeof(struct msqid_ds) * msginfo.msgmni);
! 226: kvm_read(kd, (u_long) msqids, xmsqids, sizeof(struct msqid_ds) * msginfo.msgmni);
! 227:
! 228: printf("Message Queues:\n");
! 229: printf("T ID KEY MODE OWNER GROUP");
! 230: if (option & CREATOR)
! 231: printf(" CREATOR CGROUP");
! 232: if (option & OUTSTANDING)
! 233: printf(" CBYTES QNUM");
! 234: if (option & BIGGEST)
! 235: printf(" QBYTES");
! 236: if (option & PID)
! 237: printf(" LSPID LRPID");
! 238: if (option & TIME)
! 239: printf(" STIME RTIME CTIME");
! 240: printf("\n");
! 241: for (i = 0; i < msginfo.msgmni; i += 1) {
! 242: if (xmsqids[i].msg_qbytes != 0) {
! 243: char stime_buf[100], rtime_buf[100],
! 244: ctime_buf[100];
! 245: struct msqid_ds *msqptr = &xmsqids[i];
! 246:
! 247: cvt_time(msqptr->msg_stime, stime_buf);
! 248: cvt_time(msqptr->msg_rtime, rtime_buf);
! 249: cvt_time(msqptr->msg_ctime, ctime_buf);
! 250:
! 251: printf("q %6d %10d %s %8s %8s",
! 252: IXSEQ_TO_IPCID(i, msqptr->msg_perm),
! 253: msqptr->msg_perm.key,
! 254: fmt_perm(msqptr->msg_perm.mode),
! 255: user_from_uid(msqptr->msg_perm.uid, 0),
! 256: group_from_gid(msqptr->msg_perm.gid, 0));
! 257:
! 258: if (option & CREATOR)
! 259: printf(" %8s %8s",
! 260: user_from_uid(msqptr->msg_perm.cuid, 0),
! 261: group_from_gid(msqptr->msg_perm.cgid, 0));
! 262:
! 263: if (option & OUTSTANDING)
! 264: printf(" %6d %6d",
! 265: msqptr->msg_cbytes,
! 266: msqptr->msg_qnum);
! 267:
! 268: if (option & BIGGEST)
! 269: printf(" %6d",
! 270: msqptr->msg_qbytes);
! 271:
! 272: if (option & PID)
! 273: printf(" %6d %6d",
! 274: msqptr->msg_lspid,
! 275: msqptr->msg_lrpid);
! 276:
! 277: if (option & TIME)
! 278: printf("%s %s %s",
! 279: stime_buf,
! 280: rtime_buf,
! 281: ctime_buf);
! 282:
! 283: printf("\n");
! 284: }
! 285: }
! 286: printf("\n");
! 287: }
! 288: } else
! 289: if (display & (MSGINFO | MSGTOTAL)) {
! 290: fprintf(stderr,
! 291: "SVID messages facility not configured in the system\n");
! 292: }
! 293: if ((display & (SHMINFO | SHMTOTAL)) &&
! 294: kvm_read(kd, symbols[X_SHMINFO].n_value, &shminfo, sizeof(shminfo))) {
! 295: if (display & SHMTOTAL) {
! 296: printf("shminfo:\n");
! 297: printf("\tshmmax: %7d\t(max shared memory segment size)\n",
! 298: shminfo.shmmax);
! 299: printf("\tshmmin: %7d\t(min shared memory segment size)\n",
! 300: shminfo.shmmin);
! 301: printf("\tshmmni: %7d\t(max number of shared memory identifiers)\n",
! 302: shminfo.shmmni);
! 303: printf("\tshmseg: %7d\t(max shared memory segments per process)\n",
! 304: shminfo.shmseg);
! 305: printf("\tshmall: %7d\t(max amount of shared memory in pages)\n\n",
! 306: shminfo.shmall);
! 307: }
! 308: if (display & SHMINFO) {
! 309: struct shmid_ds *xshmids;
! 310:
! 311: kvm_read(kd, symbols[X_SHMSEGS].n_value, &shmsegs, sizeof(shmsegs));
! 312: xshmids = malloc(sizeof(struct shmid_ds) * msginfo.msgmni);
! 313: kvm_read(kd, (u_long) shmsegs, xshmids, sizeof(struct shmid_ds) *
! 314: shminfo.shmmni);
! 315:
! 316: printf("Shared Memory:\n");
! 317: printf("T ID KEY MODE OWNER GROUP");
! 318: if (option & CREATOR)
! 319: printf(" CREATOR CGROUP");
! 320: if (option & OUTSTANDING)
! 321: printf(" NATTCH");
! 322: if (option & BIGGEST)
! 323: printf(" SEGSZ");
! 324: if (option & PID)
! 325: printf(" CPID LPID");
! 326: if (option & TIME)
! 327: printf(" ATIME DTIME CTIME");
! 328: printf("\n");
! 329: for (i = 0; i < shminfo.shmmni; i += 1) {
! 330: if (xshmids[i].shm_perm.mode & 0x0800) {
! 331: char atime_buf[100], dtime_buf[100],
! 332: ctime_buf[100];
! 333: struct shmid_ds *shmptr = &xshmids[i];
! 334:
! 335: cvt_time(shmptr->shm_atime, atime_buf);
! 336: cvt_time(shmptr->shm_dtime, dtime_buf);
! 337: cvt_time(shmptr->shm_ctime, ctime_buf);
! 338:
! 339: printf("m %6d %10d %s %8s %8s",
! 340: IXSEQ_TO_IPCID(i, shmptr->shm_perm),
! 341: shmptr->shm_perm.key,
! 342: fmt_perm(shmptr->shm_perm.mode),
! 343: user_from_uid(shmptr->shm_perm.uid, 0),
! 344: group_from_gid(shmptr->shm_perm.gid, 0));
! 345:
! 346: if (option & CREATOR)
! 347: printf(" %8s %8s",
! 348: user_from_uid(shmptr->shm_perm.cuid, 0),
! 349: group_from_gid(shmptr->shm_perm.cgid, 0));
! 350:
! 351: if (option & OUTSTANDING)
! 352: printf(" %6d",
! 353: shmptr->shm_nattch);
! 354:
! 355: if (option & BIGGEST)
! 356: printf(" %6d",
! 357: shmptr->shm_segsz);
! 358:
! 359: if (option & PID)
! 360: printf(" %6d %6d",
! 361: shmptr->shm_cpid,
! 362: shmptr->shm_lpid);
! 363:
! 364: if (option & TIME)
! 365: printf("%s %s %s",
! 366: atime_buf,
! 367: dtime_buf,
! 368: ctime_buf);
! 369:
! 370: printf("\n");
! 371: }
! 372: }
! 373: printf("\n");
! 374: }
! 375: } else
! 376: if (display & (SHMINFO | SHMTOTAL)) {
! 377: fprintf(stderr,
! 378: "SVID shared memory facility not configured in the system\n");
! 379: }
! 380: if ((display & (SEMINFO | SEMTOTAL)) &&
! 381: kvm_read(kd, symbols[X_SEMINFO].n_value, &seminfo, sizeof(seminfo))) {
! 382: struct semid_ds *xsema;
! 383:
! 384: if (display & SEMTOTAL) {
! 385: printf("seminfo:\n");
! 386: printf("\tsemmap: %6d\t(# of entries in semaphore map)\n",
! 387: seminfo.semmap);
! 388: printf("\tsemmni: %6d\t(# of semaphore identifiers)\n",
! 389: seminfo.semmni);
! 390: printf("\tsemmns: %6d\t(# of semaphores in system)\n",
! 391: seminfo.semmns);
! 392: printf("\tsemmnu: %6d\t(# of undo structures in system)\n",
! 393: seminfo.semmnu);
! 394: printf("\tsemmsl: %6d\t(max # of semaphores per id)\n",
! 395: seminfo.semmsl);
! 396: printf("\tsemopm: %6d\t(max # of operations per semop call)\n",
! 397: seminfo.semopm);
! 398: printf("\tsemume: %6d\t(max # of undo entries per process)\n",
! 399: seminfo.semume);
! 400: printf("\tsemusz: %6d\t(size in bytes of undo structure)\n",
! 401: seminfo.semusz);
! 402: printf("\tsemvmx: %6d\t(semaphore maximum value)\n",
! 403: seminfo.semvmx);
! 404: printf("\tsemaem: %6d\t(adjust on exit max value)\n\n",
! 405: seminfo.semaem);
! 406: }
! 407: if (display & SEMINFO) {
! 408: if (semconfig(SEM_CONFIG_FREEZE) != 0) {
! 409: perror("semconfig");
! 410: fprintf(stderr,
! 411: "Can't lock semaphore facility - winging it...\n");
! 412: }
! 413: kvm_read(kd, symbols[X_SEMA].n_value, &sema, sizeof(sema));
! 414: xsema = malloc(sizeof(struct semid_ds) * seminfo.semmni);
! 415: kvm_read(kd, (u_long) sema, xsema, sizeof(struct semid_ds) * seminfo.semmni);
! 416:
! 417: printf("Semaphores:\n");
! 418: printf("T ID KEY MODE OWNER GROUP");
! 419: if (option & CREATOR)
! 420: printf(" CREATOR CGROUP");
! 421: if (option & BIGGEST)
! 422: printf(" NSEMS");
! 423: if (option & TIME)
! 424: printf(" OTIME CTIME");
! 425: printf("\n");
! 426: for (i = 0; i < seminfo.semmni; i += 1) {
! 427: if ((xsema[i].sem_perm.mode & SEM_ALLOC) != 0) {
! 428: char ctime_buf[100], otime_buf[100];
! 429: struct semid_ds *semaptr = &xsema[i];
! 430: int j, value;
! 431: union semun junk;
! 432:
! 433: cvt_time(semaptr->sem_otime, otime_buf);
! 434: cvt_time(semaptr->sem_ctime, ctime_buf);
! 435:
! 436: printf("s %6d %10d %s %8s %8s",
! 437: IXSEQ_TO_IPCID(i, semaptr->sem_perm),
! 438: semaptr->sem_perm.key,
! 439: fmt_perm(semaptr->sem_perm.mode),
! 440: user_from_uid(semaptr->sem_perm.uid, 0),
! 441: group_from_gid(semaptr->sem_perm.gid, 0));
! 442:
! 443: if (option & CREATOR)
! 444: printf(" %8s %8s",
! 445: user_from_uid(semaptr->sem_perm.cuid, 0),
! 446: group_from_gid(semaptr->sem_perm.cgid, 0));
! 447:
! 448: if (option & BIGGEST)
! 449: printf(" %6d",
! 450: semaptr->sem_nsems);
! 451:
! 452: if (option & TIME)
! 453: printf("%s %s",
! 454: otime_buf,
! 455: ctime_buf);
! 456:
! 457: printf("\n");
! 458: }
! 459: }
! 460:
! 461: (void) semconfig(SEM_CONFIG_THAW);
! 462:
! 463: printf("\n");
! 464: }
! 465: } else
! 466: if (display & (SEMINFO | SEMTOTAL)) {
! 467: fprintf(stderr, "SVID semaphores facility not configured in the system\n");
! 468: }
! 469: kvm_close(kd);
! 470:
! 471: exit(0);
! 472: }
! 473:
! 474: void
! 475: usage()
! 476: {
! 477:
! 478: fprintf(stderr,
! 479: "usage: ipcs [-abcmopqst] [-C corefile] [-N namelist]\n");
! 480: exit(1);
! 481: }