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 __FBSDID("$FreeBSD$"); 30 31 #include <assert.h> 32 #include <err.h> 33 #include <fcntl.h> 34 #include <grp.h> 35 #include <kvm.h> 36 #include <nlist.h> 37 #include <limits.h> 38 #include <paths.h> 39 #include <pwd.h> 40 #include <stddef.h> 41 #include <stdio.h> 42 #include <stdlib.h> 43 #include <string.h> 44 #include <unistd.h> 45 46 #include <sys/types.h> 47 #include <sys/param.h> 48 #include <sys/time.h> 49 #include <sys/proc.h> 50 #include <sys/sysctl.h> 51 #define _KERNEL 52 #include <sys/ipc.h> 53 #include <sys/sem.h> 54 #include <sys/shm.h> 55 #include <sys/msg.h> 56 57 /* SysCtlGatherStruct structure. */ 58 struct scgs_vector { 59 const char *sysctl; 60 off_t offset; 61 size_t size; 62 }; 63 64 int use_sysctl = 1; 65 struct semid_kernel *sema; 66 struct seminfo seminfo; 67 struct msginfo msginfo; 68 struct msqid_kernel *msqids; 69 struct shminfo shminfo; 70 struct shmid_kernel *shmsegs; 71 72 char *fmt_perm(u_short); 73 void cvt_time(time_t, char *); 74 void sysctlgatherstruct(void *addr, size_t size, struct scgs_vector *vec); 75 void kget(int idx, void *addr, size_t size); 76 void usage(void); 77 uid_t user2uid(char *username); 78 79 static struct nlist symbols[] = { 80 {"sema"}, 81 #define X_SEMA 0 82 {"seminfo"}, 83 #define X_SEMINFO 1 84 {"msginfo"}, 85 #define X_MSGINFO 2 86 {"msqids"}, 87 #define X_MSQIDS 3 88 {"shminfo"}, 89 #define X_SHMINFO 4 90 {"shmsegs"}, 91 #define X_SHMSEGS 5 92 {NULL} 93 }; 94 95 #define SHMINFO_XVEC \ 96 X(shmmax, sizeof(u_long)) \ 97 X(shmmin, sizeof(u_long)) \ 98 X(shmmni, sizeof(u_long)) \ 99 X(shmseg, sizeof(u_long)) \ 100 X(shmall, sizeof(u_long)) 101 102 #define SEMINFO_XVEC \ 103 X(semmap, sizeof(int)) \ 104 X(semmni, sizeof(int)) \ 105 X(semmns, sizeof(int)) \ 106 X(semmnu, sizeof(int)) \ 107 X(semmsl, sizeof(int)) \ 108 X(semopm, sizeof(int)) \ 109 X(semume, sizeof(int)) \ 110 X(semusz, sizeof(int)) \ 111 X(semvmx, sizeof(int)) \ 112 X(semaem, sizeof(int)) 113 114 #define MSGINFO_XVEC \ 115 X(msgmax, sizeof(int)) \ 116 X(msgmni, sizeof(int)) \ 117 X(msgmnb, sizeof(int)) \ 118 X(msgtql, sizeof(int)) \ 119 X(msgssz, sizeof(int)) \ 120 X(msgseg, sizeof(int)) 121 122 #define X(a, b) { "kern.ipc." #a, offsetof(TYPEC, a), (b) }, 123 #define TYPEC struct shminfo 124 struct scgs_vector shminfo_scgsv[] = { SHMINFO_XVEC { NULL } }; 125 #undef TYPEC 126 #define TYPEC struct seminfo 127 struct scgs_vector seminfo_scgsv[] = { SEMINFO_XVEC { NULL } }; 128 #undef TYPEC 129 #define TYPEC struct msginfo 130 struct scgs_vector msginfo_scgsv[] = { MSGINFO_XVEC { NULL } }; 131 #undef TYPEC 132 #undef X 133 134 static kvm_t *kd; 135 136 char * 137 fmt_perm(u_short mode) 138 { 139 static char buffer[100]; 140 141 buffer[0] = '-'; 142 buffer[1] = '-'; 143 buffer[2] = ((mode & 0400) ? 'r' : '-'); 144 buffer[3] = ((mode & 0200) ? 'w' : '-'); 145 buffer[4] = ((mode & 0100) ? 'a' : '-'); 146 buffer[5] = ((mode & 0040) ? 'r' : '-'); 147 buffer[6] = ((mode & 0020) ? 'w' : '-'); 148 buffer[7] = ((mode & 0010) ? 'a' : '-'); 149 buffer[8] = ((mode & 0004) ? 'r' : '-'); 150 buffer[9] = ((mode & 0002) ? 'w' : '-'); 151 buffer[10] = ((mode & 0001) ? 'a' : '-'); 152 buffer[11] = '\0'; 153 return (&buffer[0]); 154 } 155 156 void 157 cvt_time(time_t t, char *buf) 158 { 159 struct tm *tm; 160 161 if (t == 0) { 162 strcpy(buf, "no-entry"); 163 } else { 164 tm = localtime(&t); 165 sprintf(buf, "%2d:%02d:%02d", 166 tm->tm_hour, tm->tm_min, tm->tm_sec); 167 } 168 } 169 #define SHMINFO 1 170 #define SHMTOTAL 2 171 #define MSGINFO 4 172 #define MSGTOTAL 8 173 #define SEMINFO 16 174 #define SEMTOTAL 32 175 176 #define BIGGEST 1 177 #define CREATOR 2 178 #define OUTSTANDING 4 179 #define PID 8 180 #define TIME 16 181 182 int 183 main(int argc, char *argv[]) 184 { 185 int display = SHMINFO | MSGINFO | SEMINFO; 186 int option = 0; 187 char *core = NULL, *user = NULL, *namelist = NULL; 188 char kvmoferr[_POSIX2_LINE_MAX]; /* Error buf for kvm_openfiles. */ 189 int i; 190 uid_t uid; 191 192 while ((i = getopt(argc, argv, "MmQqSsabC:cN:optTu:y")) != -1) 193 switch (i) { 194 case 'M': 195 display = SHMTOTAL; 196 break; 197 case 'm': 198 display = SHMINFO; 199 break; 200 case 'Q': 201 display = MSGTOTAL; 202 break; 203 case 'q': 204 display = MSGINFO; 205 break; 206 case 'S': 207 display = SEMTOTAL; 208 break; 209 case 's': 210 display = SEMINFO; 211 break; 212 case 'T': 213 display = SHMTOTAL | MSGTOTAL | SEMTOTAL; 214 break; 215 case 'a': 216 option |= BIGGEST | CREATOR | OUTSTANDING | PID | TIME; 217 break; 218 case 'b': 219 option |= BIGGEST; 220 break; 221 case 'C': 222 core = optarg; 223 break; 224 case 'c': 225 option |= CREATOR; 226 break; 227 case 'N': 228 namelist = optarg; 229 break; 230 case 'o': 231 option |= OUTSTANDING; 232 break; 233 case 'p': 234 option |= PID; 235 break; 236 case 't': 237 option |= TIME; 238 break; 239 case 'y': 240 use_sysctl = 0; 241 break; 242 case 'u': 243 user = optarg; 244 uid = user2uid(user); 245 break; 246 default: 247 usage(); 248 } 249 250 /* 251 * If paths to the exec file or core file were specified, we 252 * aren't operating on the running kernel, so we can't use 253 * sysctl. 254 */ 255 if (namelist != NULL || core != NULL) 256 use_sysctl = 0; 257 258 if (!use_sysctl) { 259 kd = kvm_openfiles(namelist, core, NULL, O_RDONLY, kvmoferr); 260 if (kd == NULL) 261 errx(1, "kvm_openfiles: %s", kvmoferr); 262 switch (kvm_nlist(kd, symbols)) { 263 case 0: 264 break; 265 case -1: 266 errx(1, "unable to read kernel symbol table"); 267 default: 268 #ifdef notdef /* they'll be told more civilly later */ 269 warnx("nlist failed"); 270 for (i = 0; symbols[i].n_name != NULL; i++) 271 if (symbols[i].n_value == 0) 272 warnx("symbol %s not found", 273 symbols[i].n_name); 274 #endif 275 break; 276 } 277 } 278 279 kget(X_MSGINFO, &msginfo, sizeof(msginfo)); 280 if ((display & (MSGINFO | MSGTOTAL))) { 281 if (display & MSGTOTAL) { 282 printf("msginfo:\n"); 283 printf("\tmsgmax: %12d\t(max characters in a message)\n", 284 msginfo.msgmax); 285 printf("\tmsgmni: %12d\t(# of message queues)\n", 286 msginfo.msgmni); 287 printf("\tmsgmnb: %12d\t(max characters in a message queue)\n", 288 msginfo.msgmnb); 289 printf("\tmsgtql: %12d\t(max # of messages in system)\n", 290 msginfo.msgtql); 291 printf("\tmsgssz: %12d\t(size of a message segment)\n", 292 msginfo.msgssz); 293 printf("\tmsgseg: %12d\t(# of message segments in system)\n\n", 294 msginfo.msgseg); 295 } 296 if (display & MSGINFO) { 297 struct msqid_kernel *kxmsqids; 298 size_t kxmsqids_len; 299 300 301 kxmsqids_len = sizeof(struct msqid_kernel) * msginfo.msgmni; 302 kxmsqids = malloc(kxmsqids_len); 303 kget(X_MSQIDS, kxmsqids, kxmsqids_len); 304 305 printf("Message Queues:\n"); 306 printf("T %12s %12s %-11s %-8s %-8s", "ID", "KEY", "MODE", 307 "OWNER", "GROUP"); 308 if (option & CREATOR) 309 printf(" %-8s %-8s", "CREATOR", "CGROUP"); 310 if (option & OUTSTANDING) 311 printf(" %20s %20s", "CBYTES", "QNUM"); 312 if (option & BIGGEST) 313 printf(" %20s", "QBYTES"); 314 if (option & PID) 315 printf(" %12s %12s", "LSPID", "LRPID"); 316 if (option & TIME) 317 printf(" %-8s %-8s %-8s", "STIME", "RTIME", "CTIME"); 318 printf("\n"); 319 for (i = 0; i < msginfo.msgmni; i += 1) { 320 if (kxmsqids[i].u.msg_qbytes != 0) { 321 char stime_buf[100], rtime_buf[100], 322 ctime_buf[100]; 323 struct msqid_kernel *kmsqptr = &kxmsqids[i]; 324 325 if (user) 326 if (uid != kmsqptr->u.msg_perm.uid) 327 continue; 328 cvt_time(kmsqptr->u.msg_stime, stime_buf); 329 cvt_time(kmsqptr->u.msg_rtime, rtime_buf); 330 cvt_time(kmsqptr->u.msg_ctime, ctime_buf); 331 332 printf("q %12d %12d %s %8s %8s", 333 IXSEQ_TO_IPCID(i, kmsqptr->u.msg_perm), 334 (int)kmsqptr->u.msg_perm.key, 335 fmt_perm(kmsqptr->u.msg_perm.mode), 336 user_from_uid(kmsqptr->u.msg_perm.uid, 0), 337 group_from_gid(kmsqptr->u.msg_perm.gid, 0)); 338 339 if (option & CREATOR) 340 printf(" %8s %8s", 341 user_from_uid(kmsqptr->u.msg_perm.cuid, 0), 342 group_from_gid(kmsqptr->u.msg_perm.cgid, 0)); 343 344 if (option & OUTSTANDING) 345 printf(" %12lu %12lu", 346 kmsqptr->u.msg_cbytes, 347 kmsqptr->u.msg_qnum); 348 349 if (option & BIGGEST) 350 printf(" %20lu", 351 kmsqptr->u.msg_qbytes); 352 353 if (option & PID) 354 printf(" %12d %12d", 355 kmsqptr->u.msg_lspid, 356 kmsqptr->u.msg_lrpid); 357 358 if (option & TIME) 359 printf(" %s %s %s", 360 stime_buf, 361 rtime_buf, 362 ctime_buf); 363 364 printf("\n"); 365 } 366 } 367 printf("\n"); 368 } 369 } else 370 if (display & (MSGINFO | MSGTOTAL)) { 371 fprintf(stderr, 372 "SVID messages facility not configured in the system\n"); 373 } 374 375 kget(X_SHMINFO, &shminfo, sizeof(shminfo)); 376 if ((display & (SHMINFO | SHMTOTAL))) { 377 if (display & SHMTOTAL) { 378 printf("shminfo:\n"); 379 printf("\tshmmax: %12d\t(max shared memory segment size)\n", 380 shminfo.shmmax); 381 printf("\tshmmin: %12d\t(min shared memory segment size)\n", 382 shminfo.shmmin); 383 printf("\tshmmni: %12d\t(max number of shared memory identifiers)\n", 384 shminfo.shmmni); 385 printf("\tshmseg: %12d\t(max shared memory segments per process)\n", 386 shminfo.shmseg); 387 printf("\tshmall: %12d\t(max amount of shared memory in pages)\n\n", 388 shminfo.shmall); 389 } 390 if (display & SHMINFO) { 391 struct shmid_kernel *kxshmids; 392 size_t kxshmids_len; 393 394 kxshmids_len = sizeof(struct shmid_kernel) * shminfo.shmmni; 395 kxshmids = malloc(kxshmids_len); 396 kget(X_SHMSEGS, kxshmids, kxshmids_len); 397 398 printf("Shared Memory:\n"); 399 printf("T %12s %12s %-11s %-8s %-8s", "ID", "KEY", "MODE", 400 "OWNER", "GROUP"); 401 if (option & CREATOR) 402 printf(" %-8s %-8s", "CREATOR", "CGROUP"); 403 if (option & OUTSTANDING) 404 printf(" %12s", "NATTCH"); 405 if (option & BIGGEST) 406 printf(" %12s", "SEGSZ"); 407 if (option & PID) 408 printf(" %12s %12s", "CPID", "LPID"); 409 if (option & TIME) 410 printf(" %-8s %-8s %-8s", "ATIME", "DTIME", "CTIME"); 411 printf("\n"); 412 for (i = 0; i < shminfo.shmmni; i += 1) { 413 if (kxshmids[i].u.shm_perm.mode & 0x0800) { 414 char atime_buf[100], dtime_buf[100], 415 ctime_buf[100]; 416 struct shmid_kernel *kshmptr = &kxshmids[i]; 417 418 if (user) 419 if (uid != kshmptr->u.shm_perm.uid) 420 continue; 421 cvt_time(kshmptr->u.shm_atime, atime_buf); 422 cvt_time(kshmptr->u.shm_dtime, dtime_buf); 423 cvt_time(kshmptr->u.shm_ctime, ctime_buf); 424 425 printf("m %12d %12d %s %8s %8s", 426 IXSEQ_TO_IPCID(i, kshmptr->u.shm_perm), 427 (int)kshmptr->u.shm_perm.key, 428 fmt_perm(kshmptr->u.shm_perm.mode), 429 user_from_uid(kshmptr->u.shm_perm.uid, 0), 430 group_from_gid(kshmptr->u.shm_perm.gid, 0)); 431 432 if (option & CREATOR) 433 printf(" %8s %8s", 434 user_from_uid(kshmptr->u.shm_perm.cuid, 0), 435 group_from_gid(kshmptr->u.shm_perm.cgid, 0)); 436 437 if (option & OUTSTANDING) 438 printf(" %12d", 439 kshmptr->u.shm_nattch); 440 441 if (option & BIGGEST) 442 printf(" %12d", 443 kshmptr->u.shm_segsz); 444 445 if (option & PID) 446 printf(" %12d %12d", 447 kshmptr->u.shm_cpid, 448 kshmptr->u.shm_lpid); 449 450 if (option & TIME) 451 printf(" %s %s %s", 452 atime_buf, 453 dtime_buf, 454 ctime_buf); 455 456 printf("\n"); 457 } 458 } 459 printf("\n"); 460 } 461 } else 462 if (display & (SHMINFO | SHMTOTAL)) { 463 fprintf(stderr, 464 "SVID shared memory facility not configured in the system\n"); 465 } 466 467 kget(X_SEMINFO, &seminfo, sizeof(seminfo)); 468 if ((display & (SEMINFO | SEMTOTAL))) { 469 struct semid_kernel *kxsema; 470 size_t kxsema_len; 471 472 if (display & SEMTOTAL) { 473 printf("seminfo:\n"); 474 printf("\tsemmap: %12d\t(# of entries in semaphore map)\n", 475 seminfo.semmap); 476 printf("\tsemmni: %12d\t(# of semaphore identifiers)\n", 477 seminfo.semmni); 478 printf("\tsemmns: %12d\t(# of semaphores in system)\n", 479 seminfo.semmns); 480 printf("\tsemmnu: %12d\t(# of undo structures in system)\n", 481 seminfo.semmnu); 482 printf("\tsemmsl: %12d\t(max # of semaphores per id)\n", 483 seminfo.semmsl); 484 printf("\tsemopm: %12d\t(max # of operations per semop call)\n", 485 seminfo.semopm); 486 printf("\tsemume: %12d\t(max # of undo entries per process)\n", 487 seminfo.semume); 488 printf("\tsemusz: %12d\t(size in bytes of undo structure)\n", 489 seminfo.semusz); 490 printf("\tsemvmx: %12d\t(semaphore maximum value)\n", 491 seminfo.semvmx); 492 printf("\tsemaem: %12d\t(adjust on exit max value)\n\n", 493 seminfo.semaem); 494 } 495 if (display & SEMINFO) { 496 kxsema_len = sizeof(struct semid_kernel) * seminfo.semmni; 497 kxsema = malloc(kxsema_len); 498 kget(X_SEMA, kxsema, kxsema_len); 499 500 printf("Semaphores:\n"); 501 printf("T %12s %12s %-11s %-8s %-8s", "ID", "KEY", "MODE", 502 "OWNER", "GROUP"); 503 if (option & CREATOR) 504 printf(" %-8s %-8s", "CREATOR", "CGROUP"); 505 if (option & BIGGEST) 506 printf(" %12s", "NSEMS"); 507 if (option & TIME) 508 printf(" %-8s %-8s", "OTIME", "CTIME"); 509 printf("\n"); 510 for (i = 0; i < seminfo.semmni; i += 1) { 511 if ((kxsema[i].u.sem_perm.mode & SEM_ALLOC) != 0) { 512 char ctime_buf[100], otime_buf[100]; 513 struct semid_kernel *ksemaptr = &kxsema[i]; 514 515 if (user) 516 if (uid != ksemaptr->u.sem_perm.uid) 517 continue; 518 cvt_time(ksemaptr->u.sem_otime, otime_buf); 519 cvt_time(ksemaptr->u.sem_ctime, ctime_buf); 520 521 printf("s %12d %12d %s %8s %8s", 522 IXSEQ_TO_IPCID(i, ksemaptr->u.sem_perm), 523 (int)ksemaptr->u.sem_perm.key, 524 fmt_perm(ksemaptr->u.sem_perm.mode), 525 user_from_uid(ksemaptr->u.sem_perm.uid, 0), 526 group_from_gid(ksemaptr->u.sem_perm.gid, 0)); 527 528 if (option & CREATOR) 529 printf(" %8s %8s", 530 user_from_uid(ksemaptr->u.sem_perm.cuid, 0), 531 group_from_gid(ksemaptr->u.sem_perm.cgid, 0)); 532 533 if (option & BIGGEST) 534 printf(" %12d", 535 ksemaptr->u.sem_nsems); 536 537 if (option & TIME) 538 printf(" %s %s", 539 otime_buf, 540 ctime_buf); 541 542 printf("\n"); 543 } 544 } 545 546 printf("\n"); 547 } 548 } else 549 if (display & (SEMINFO | SEMTOTAL)) { 550 fprintf(stderr, "SVID semaphores facility not configured in the system\n"); 551 } 552 if (!use_sysctl) 553 kvm_close(kd); 554 555 exit(0); 556 } 557 558 void 559 sysctlgatherstruct(void *addr, size_t size, struct scgs_vector *vecarr) 560 { 561 struct scgs_vector *xp; 562 size_t tsiz; 563 int rv; 564 565 for (xp = vecarr; xp->sysctl != NULL; xp++) { 566 assert(xp->offset <= size); 567 tsiz = xp->size; 568 rv = sysctlbyname(xp->sysctl, (char *)addr + xp->offset, 569 &tsiz, NULL, 0); 570 if (rv == -1) 571 err(1, "sysctlbyname: %s", xp->sysctl); 572 if (tsiz != xp->size) 573 errx(1, "%s size mismatch (expected %d, got %d)", 574 xp->sysctl, xp->size, tsiz); 575 } 576 } 577 578 void 579 kget(int idx, void *addr, size_t size) 580 { 581 char *symn; /* symbol name */ 582 size_t tsiz; 583 int rv; 584 unsigned long kaddr; 585 const char *sym2sysctl[] = { /* symbol to sysctl name table */ 586 "kern.ipc.sema", 587 "kern.ipc.seminfo", 588 "kern.ipc.msginfo", 589 "kern.ipc.msqids", 590 "kern.ipc.shminfo", 591 "kern.ipc.shmsegs" }; 592 593 assert((unsigned)idx <= sizeof(sym2sysctl) / sizeof(*sym2sysctl)); 594 if (!use_sysctl) { 595 symn = symbols[idx].n_name; 596 if (*symn == '_') 597 symn++; 598 if (symbols[idx].n_type == 0 || symbols[idx].n_value == 0) 599 errx(1, "symbol %s undefined", symn); 600 /* 601 * For some symbols, the value we retrieve is 602 * actually a pointer; since we want the actual value, 603 * we have to manually dereference it. 604 */ 605 switch (idx) { 606 case X_MSQIDS: 607 tsiz = sizeof(msqids); 608 rv = kvm_read(kd, symbols[idx].n_value, 609 &msqids, tsiz); 610 kaddr = (u_long)msqids; 611 break; 612 case X_SHMSEGS: 613 tsiz = sizeof(shmsegs); 614 rv = kvm_read(kd, symbols[idx].n_value, 615 &shmsegs, tsiz); 616 kaddr = (u_long)shmsegs; 617 break; 618 case X_SEMA: 619 tsiz = sizeof(sema); 620 rv = kvm_read(kd, symbols[idx].n_value, 621 &sema, tsiz); 622 kaddr = (u_long)sema; 623 break; 624 default: 625 rv = tsiz = 0; 626 kaddr = symbols[idx].n_value; 627 break; 628 } 629 if ((unsigned)rv != tsiz) 630 errx(1, "%s: %s", symn, kvm_geterr(kd)); 631 if ((unsigned)kvm_read(kd, kaddr, addr, size) != size) 632 errx(1, "%s: %s", symn, kvm_geterr(kd)); 633 } else { 634 switch (idx) { 635 case X_SHMINFO: 636 sysctlgatherstruct(addr, size, shminfo_scgsv); 637 break; 638 case X_SEMINFO: 639 sysctlgatherstruct(addr, size, seminfo_scgsv); 640 break; 641 case X_MSGINFO: 642 sysctlgatherstruct(addr, size, msginfo_scgsv); 643 break; 644 default: 645 tsiz = size; 646 rv = sysctlbyname(sym2sysctl[idx], addr, &tsiz, 647 NULL, 0); 648 if (rv == -1) 649 err(1, "sysctlbyname: %s", sym2sysctl[idx]); 650 if (tsiz != size) 651 errx(1, "%s size mismatch " 652 "(expected %d, got %d)", 653 sym2sysctl[idx], size, tsiz); 654 break; 655 } 656 } 657 } 658 659 uid_t 660 user2uid(char *username) 661 { 662 struct passwd *pwd; 663 uid_t uid; 664 char *r; 665 666 uid = strtoul(username, &r, 0); 667 if (!*r && r != username) 668 return (uid); 669 if ((pwd = getpwnam(username)) == NULL) 670 errx(1, "getpwnam failed: No such user"); 671 endpwent(); 672 return (pwd->pw_uid); 673 } 674 675 void 676 usage(void) 677 { 678 679 fprintf(stderr, 680 "usage: ipcs [-abcmopqstyMQST] [-C corefile] [-N namelist] [-u user]\n"); 681 exit(1); 682 } 683