xref: /onnv-gate/usr/src/cmd/ipcs/ipcs.c (revision 3797:2436612507a3)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*3797Sceastha  * Common Development and Distribution License (the "License").
6*3797Sceastha  * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate  *
80Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate  * See the License for the specific language governing permissions
110Sstevel@tonic-gate  * and limitations under the License.
120Sstevel@tonic-gate  *
130Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate  *
190Sstevel@tonic-gate  * CDDL HEADER END
200Sstevel@tonic-gate  */
210Sstevel@tonic-gate /*
22*3797Sceastha  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
230Sstevel@tonic-gate  * Use is subject to license terms.
240Sstevel@tonic-gate  */
250Sstevel@tonic-gate 
260Sstevel@tonic-gate /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
270Sstevel@tonic-gate /*	  All Rights Reserved  	*/
280Sstevel@tonic-gate 
290Sstevel@tonic-gate 
300Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
310Sstevel@tonic-gate 
320Sstevel@tonic-gate /*
330Sstevel@tonic-gate  * ipcs - IPC status
340Sstevel@tonic-gate  *
350Sstevel@tonic-gate  * Examine and print certain things about
360Sstevel@tonic-gate  * message queues, semaphores and shared memory.
370Sstevel@tonic-gate  *
380Sstevel@tonic-gate  * IPC information is obtained via msgctl64, semctl64 and shmctl64.
390Sstevel@tonic-gate  * As of SunOS 5.8, the IPC identifiers are obtained from msgids(),
400Sstevel@tonic-gate  * semids(), and shmids() rather than reading them from /dev/kmem.
410Sstevel@tonic-gate  * This ensures that the information in each msgid_ds, semid_ds or
420Sstevel@tonic-gate  * shmid_ds data structure that we obtain is complete and consistent,
430Sstevel@tonic-gate  * and allows us not to be a setgid-sys isaexec process.
440Sstevel@tonic-gate  */
450Sstevel@tonic-gate 
460Sstevel@tonic-gate #include <sys/types.h>
470Sstevel@tonic-gate #include <sys/ipc.h>
480Sstevel@tonic-gate #include <sys/ipc_impl.h>
490Sstevel@tonic-gate #include <sys/msg.h>
500Sstevel@tonic-gate #include <sys/sem.h>
510Sstevel@tonic-gate #include <sys/shm.h>
520Sstevel@tonic-gate #include <errno.h>
530Sstevel@tonic-gate #include <fcntl.h>
540Sstevel@tonic-gate #include <time.h>
550Sstevel@tonic-gate #include <grp.h>
560Sstevel@tonic-gate #include <pwd.h>
570Sstevel@tonic-gate #include <stdio.h>
580Sstevel@tonic-gate #include <stdlib.h>
590Sstevel@tonic-gate #include <ctype.h>
600Sstevel@tonic-gate #include <unistd.h>
610Sstevel@tonic-gate #include <locale.h>
620Sstevel@tonic-gate #include <langinfo.h>
630Sstevel@tonic-gate #include <string.h>
640Sstevel@tonic-gate #include <limits.h>
650Sstevel@tonic-gate #include <project.h>
660Sstevel@tonic-gate #include <zone.h>
670Sstevel@tonic-gate 
680Sstevel@tonic-gate #define	USAGE	\
690Sstevel@tonic-gate 	"usage: ipcs [-AabciJmopqstZ] [-D mtype] [-z zone]\n"
700Sstevel@tonic-gate 
710Sstevel@tonic-gate static char chdr[] = "T         ID      KEY        MODE        OWNER    GROUP";
720Sstevel@tonic-gate 						/* common header format */
730Sstevel@tonic-gate static char chdr2[] = "  CREATOR   CGROUP";	/* c option header format */
740Sstevel@tonic-gate static char chdr3[] = "         PROJECT";	/* J option header format */
750Sstevel@tonic-gate static char opts[] = "AabciJmopqstD:z:Z";	/* getopt options */
760Sstevel@tonic-gate 
770Sstevel@tonic-gate static long	mtype;		/* -D: user-supplied message type */
780Sstevel@tonic-gate static zoneid_t	zoneid;		/* -z: user-supplied zone id */
790Sstevel@tonic-gate 
800Sstevel@tonic-gate static int	bflg,		/* biggest size: */
810Sstevel@tonic-gate 				/*	segsz on m; qbytes on q; nsems on s */
820Sstevel@tonic-gate 		cflg,		/* creator's login and group names */
830Sstevel@tonic-gate 		Dflg,		/* dump contents of message queues */
840Sstevel@tonic-gate 		iflg,		/* ISM attaches */
850Sstevel@tonic-gate 		Jflg,		/* dump project name */
860Sstevel@tonic-gate 		mflg,		/* shared memory status */
870Sstevel@tonic-gate 		oflg,		/* outstanding data: */
880Sstevel@tonic-gate 				/*	nattch on m; cbytes, qnum on q */
890Sstevel@tonic-gate 		pflg,		/* process id's: lrpid, lspid on q; */
900Sstevel@tonic-gate 				/*	cpid, lpid on m */
910Sstevel@tonic-gate 		qflg,		/* message queue status */
920Sstevel@tonic-gate 		sflg,		/* semaphore status */
930Sstevel@tonic-gate 		tflg,		/* times: atime, ctime, dtime on m;	*/
940Sstevel@tonic-gate 				/*	ctime, rtime, stime on q;	*/
950Sstevel@tonic-gate 				/*	ctime, otime on s */
960Sstevel@tonic-gate 		zflg,		/* show only objects from specified zone */
970Sstevel@tonic-gate 		Zflg,		/* display zone name */
980Sstevel@tonic-gate 		err;		/* option error count */
990Sstevel@tonic-gate 
1000Sstevel@tonic-gate static void hp(char, char *, struct ipc_perm64 *, int);
1010Sstevel@tonic-gate static void jp(struct ipc_perm64 *);
1020Sstevel@tonic-gate static void tp(ipc_time_t);
1030Sstevel@tonic-gate static void dumpmsgq(int);
1040Sstevel@tonic-gate static void dumpmsg(long, char *, size_t);
1050Sstevel@tonic-gate static zoneid_t getzone(char *);
1060Sstevel@tonic-gate static void printzone(zoneid_t);
1070Sstevel@tonic-gate 
1080Sstevel@tonic-gate int
main(int argc,char * argv[])1090Sstevel@tonic-gate main(int argc, char *argv[])
1100Sstevel@tonic-gate {
1110Sstevel@tonic-gate 	static	int	*ids;	/* array of IPC identifiers from *ids() */
1120Sstevel@tonic-gate 	static	uint_t	nids;	/* number of entries in ids */
1130Sstevel@tonic-gate 
1140Sstevel@tonic-gate 	int	o;	/* option flag */
1150Sstevel@tonic-gate 	int	id;	/* IPC identifier */
1160Sstevel@tonic-gate 	int	i;
1170Sstevel@tonic-gate 	uint_t	n;	/* table size */
1180Sstevel@tonic-gate 	time_t	now;	/* date */
1190Sstevel@tonic-gate 	char	tbuf[BUFSIZ];
1200Sstevel@tonic-gate 	char	*dfmt;  /* date format pointer */
1210Sstevel@tonic-gate 	char	*endptr;	/* terminator for strtol() */
1220Sstevel@tonic-gate 
1230Sstevel@tonic-gate 	(void) setlocale(LC_ALL, "");
1240Sstevel@tonic-gate 	(void) textdomain(TEXT_DOMAIN);
1250Sstevel@tonic-gate 
1260Sstevel@tonic-gate 	(void) memset(tbuf, 0, sizeof (tbuf));
1270Sstevel@tonic-gate 	dfmt = nl_langinfo(_DATE_FMT);
1280Sstevel@tonic-gate 
1290Sstevel@tonic-gate 	zoneid = getzoneid();	/* default zone id if -z and -Z not used */
1300Sstevel@tonic-gate 
1310Sstevel@tonic-gate 	/* Go through the options and set flags. */
1320Sstevel@tonic-gate 	while ((o = getopt(argc, argv, opts)) != EOF) {
1330Sstevel@tonic-gate 		switch (o) {
1340Sstevel@tonic-gate 		case 'A':
1350Sstevel@tonic-gate 			bflg = cflg = iflg = oflg = pflg = tflg = Jflg = 1;
1360Sstevel@tonic-gate 			break;
1370Sstevel@tonic-gate 		case 'a':
1380Sstevel@tonic-gate 			bflg = cflg = oflg = pflg = tflg = 1;
1390Sstevel@tonic-gate 			break;
1400Sstevel@tonic-gate 		case 'b':
1410Sstevel@tonic-gate 			bflg = 1;
1420Sstevel@tonic-gate 			break;
1430Sstevel@tonic-gate 		case 'c':
1440Sstevel@tonic-gate 			cflg = 1;
1450Sstevel@tonic-gate 			break;
1460Sstevel@tonic-gate 		case 'D':
1470Sstevel@tonic-gate 			mtype = strtol(optarg, &endptr, 0);
1480Sstevel@tonic-gate 			if (endptr == optarg || *endptr != '\0') {
1490Sstevel@tonic-gate 				(void) fprintf(stderr,
1500Sstevel@tonic-gate 				    gettext("ipcs: invalid message type: %s\n"),
1510Sstevel@tonic-gate 				    optarg);
1520Sstevel@tonic-gate 				err++;
1530Sstevel@tonic-gate 				break;
1540Sstevel@tonic-gate 			}
1550Sstevel@tonic-gate 			Dflg = 1;
1560Sstevel@tonic-gate 			break;
1570Sstevel@tonic-gate 		case 'i':
1580Sstevel@tonic-gate 			iflg = 1;
1590Sstevel@tonic-gate 			break;
1600Sstevel@tonic-gate 		case 'J':
1610Sstevel@tonic-gate 			Jflg = 1;
1620Sstevel@tonic-gate 			break;
1630Sstevel@tonic-gate 		case 'm':
1640Sstevel@tonic-gate 			mflg = 1;
1650Sstevel@tonic-gate 			break;
1660Sstevel@tonic-gate 		case 'o':
1670Sstevel@tonic-gate 			oflg = 1;
1680Sstevel@tonic-gate 			break;
1690Sstevel@tonic-gate 		case 'p':
1700Sstevel@tonic-gate 			pflg = 1;
1710Sstevel@tonic-gate 			break;
1720Sstevel@tonic-gate 		case 'q':
1730Sstevel@tonic-gate 			qflg = 1;
1740Sstevel@tonic-gate 			break;
1750Sstevel@tonic-gate 		case 's':
1760Sstevel@tonic-gate 			sflg = 1;
1770Sstevel@tonic-gate 			break;
1780Sstevel@tonic-gate 		case 't':
1790Sstevel@tonic-gate 			tflg = 1;
1800Sstevel@tonic-gate 			break;
1810Sstevel@tonic-gate 		case 'z':
1820Sstevel@tonic-gate 			zflg = 1;
1830Sstevel@tonic-gate 			zoneid = getzone(optarg);
1840Sstevel@tonic-gate 			break;
1850Sstevel@tonic-gate 		case 'Z':
1860Sstevel@tonic-gate 			Zflg = 1;
1870Sstevel@tonic-gate 			break;
1880Sstevel@tonic-gate 		case '?':
1890Sstevel@tonic-gate 			err++;
1900Sstevel@tonic-gate 			break;
1910Sstevel@tonic-gate 		}
1920Sstevel@tonic-gate 	}
1930Sstevel@tonic-gate 	if (err || (optind < argc)) {
1940Sstevel@tonic-gate 		(void) fprintf(stderr, gettext(USAGE));
1950Sstevel@tonic-gate 		exit(1);
1960Sstevel@tonic-gate 	}
1970Sstevel@tonic-gate 
1980Sstevel@tonic-gate 	if ((mflg + qflg + sflg) == 0)
1990Sstevel@tonic-gate 		mflg = qflg = sflg = 1;
2000Sstevel@tonic-gate 
2010Sstevel@tonic-gate 	now = time(NULL);
2020Sstevel@tonic-gate 	(void) strftime(tbuf, sizeof (tbuf), dfmt, localtime(&now));
2030Sstevel@tonic-gate 	(void) printf(gettext("IPC status from <running system> as of %s\n"),
2040Sstevel@tonic-gate 	    tbuf);
2050Sstevel@tonic-gate 
2060Sstevel@tonic-gate 	/*
2070Sstevel@tonic-gate 	 * Print Message Queue status report.
2080Sstevel@tonic-gate 	 */
2090Sstevel@tonic-gate 	if (qflg) {
2100Sstevel@tonic-gate 		struct msqid_ds64 qds;
2110Sstevel@tonic-gate 
2120Sstevel@tonic-gate 		for (;;) {
2130Sstevel@tonic-gate 			if (msgids(ids, nids, &n) != 0) {
2140Sstevel@tonic-gate 				perror("msgids");
2150Sstevel@tonic-gate 				exit(1);
2160Sstevel@tonic-gate 			}
2170Sstevel@tonic-gate 			if (n <= nids)
2180Sstevel@tonic-gate 				break;
2190Sstevel@tonic-gate 			ids = realloc(ids, (nids = n) * sizeof (int));
2200Sstevel@tonic-gate 		}
2210Sstevel@tonic-gate 
2220Sstevel@tonic-gate 		(void) printf("%s%s%s%s%s%s%s%s\n", chdr,
2230Sstevel@tonic-gate 		    cflg ? chdr2 : "",
2240Sstevel@tonic-gate 		    oflg ? " CBYTES  QNUM" : "",
2250Sstevel@tonic-gate 		    bflg ? " QBYTES" : "",
2260Sstevel@tonic-gate 		    pflg ? " LSPID LRPID" : "",
2270Sstevel@tonic-gate 		    tflg ? "   STIME    RTIME    CTIME " : "",
2280Sstevel@tonic-gate 		    Jflg ? chdr3 : "",
2290Sstevel@tonic-gate 		    Zflg ? "     ZONE" : "");
2300Sstevel@tonic-gate 
2310Sstevel@tonic-gate 		(void) printf(gettext("Message Queues:\n"));
2320Sstevel@tonic-gate 
2330Sstevel@tonic-gate 		for (i = 0; i < n; i++) {
2340Sstevel@tonic-gate 			id = ids[i];
2350Sstevel@tonic-gate 			if (msgctl64(id, IPC_STAT64, &qds) < 0)
2360Sstevel@tonic-gate 				continue;
2370Sstevel@tonic-gate 			/* ignore zone if -Z was used and -z wasn't */
2380Sstevel@tonic-gate 			if ((zflg || !Zflg) &&
2390Sstevel@tonic-gate 			    qds.msgx_perm.ipcx_zoneid != zoneid)
2400Sstevel@tonic-gate 				continue;
2410Sstevel@tonic-gate 			hp('q', "SRrw-rw-rw-", &qds.msgx_perm, id);
2420Sstevel@tonic-gate 			if (oflg)
2430Sstevel@tonic-gate 				(void) printf(" %6llu %5llu",
2440Sstevel@tonic-gate 				    qds.msgx_cbytes, qds.msgx_qnum);
2450Sstevel@tonic-gate 			if (bflg)
2460Sstevel@tonic-gate 				(void) printf(" %6llu", qds.msgx_qbytes);
2470Sstevel@tonic-gate 			if (pflg)
2480Sstevel@tonic-gate 				(void) printf(" %5d %5d",
2490Sstevel@tonic-gate 				    (int)qds.msgx_lspid, (int)qds.msgx_lrpid);
2500Sstevel@tonic-gate 			if (tflg) {
2510Sstevel@tonic-gate 				tp(qds.msgx_stime);
2520Sstevel@tonic-gate 				tp(qds.msgx_rtime);
2530Sstevel@tonic-gate 				tp(qds.msgx_ctime);
2540Sstevel@tonic-gate 			}
2550Sstevel@tonic-gate 			if (Jflg)
2560Sstevel@tonic-gate 				jp(&qds.msgx_perm);
2570Sstevel@tonic-gate 			if (Zflg)
2580Sstevel@tonic-gate 				printzone(qds.msgx_perm.ipcx_zoneid);
2590Sstevel@tonic-gate 			(void) printf("\n");
2600Sstevel@tonic-gate 			if (Dflg)
2610Sstevel@tonic-gate 				dumpmsgq(id);
2620Sstevel@tonic-gate 		}
2630Sstevel@tonic-gate 	}
2640Sstevel@tonic-gate 
2650Sstevel@tonic-gate 	/*
2660Sstevel@tonic-gate 	 * Print Shared Memory status report.
2670Sstevel@tonic-gate 	 */
2680Sstevel@tonic-gate 	if (mflg) {
2690Sstevel@tonic-gate 		struct shmid_ds64 mds;
2700Sstevel@tonic-gate 
2710Sstevel@tonic-gate 		for (;;) {
2720Sstevel@tonic-gate 			if (shmids(ids, nids, &n) != 0) {
2730Sstevel@tonic-gate 				perror("shmids");
2740Sstevel@tonic-gate 				exit(1);
2750Sstevel@tonic-gate 			}
2760Sstevel@tonic-gate 			if (n <= nids)
2770Sstevel@tonic-gate 				break;
2780Sstevel@tonic-gate 			ids = realloc(ids, (nids = n) * sizeof (int));
2790Sstevel@tonic-gate 		}
2800Sstevel@tonic-gate 
2810Sstevel@tonic-gate 		if (!qflg || oflg || bflg || pflg || tflg || iflg)
2820Sstevel@tonic-gate 			(void) printf("%s%s%s%s%s%s%s%s%s\n", chdr,
2830Sstevel@tonic-gate 			    cflg ? chdr2 : "",
2840Sstevel@tonic-gate 			    oflg ? " NATTCH" : "",
2850Sstevel@tonic-gate 			    bflg ? "      SEGSZ" : "",
2860Sstevel@tonic-gate 			    pflg ? "  CPID  LPID" : "",
2870Sstevel@tonic-gate 			    tflg ? "   ATIME    DTIME    CTIME " : "",
2880Sstevel@tonic-gate 			    iflg ? " ISMATTCH" : "",
2890Sstevel@tonic-gate 			    Jflg ? chdr3 : "",
2900Sstevel@tonic-gate 			    Zflg ? "     ZONE" : "");
2910Sstevel@tonic-gate 
2920Sstevel@tonic-gate 		(void) printf(gettext("Shared Memory:\n"));
2930Sstevel@tonic-gate 
2940Sstevel@tonic-gate 		for (i = 0; i < n; i++) {
2950Sstevel@tonic-gate 			id = ids[i];
2960Sstevel@tonic-gate 			if (shmctl64(id, IPC_STAT64, &mds) < 0)
2970Sstevel@tonic-gate 				continue;
2980Sstevel@tonic-gate 			/* ignore zone if -Z was used and -z wasn't */
2990Sstevel@tonic-gate 			if ((zflg || !Zflg) &&
3000Sstevel@tonic-gate 			    mds.shmx_perm.ipcx_zoneid != zoneid)
3010Sstevel@tonic-gate 				continue;
3020Sstevel@tonic-gate 			hp('m', "--rw-rw-rw-", &mds.shmx_perm, id);
3030Sstevel@tonic-gate 			if (oflg)
3040Sstevel@tonic-gate 				(void) printf(" %6llu", mds.shmx_nattch);
3050Sstevel@tonic-gate 			if (bflg)
3060Sstevel@tonic-gate 				(void) printf(" %10llu", mds.shmx_segsz);
3070Sstevel@tonic-gate 			if (pflg)
3080Sstevel@tonic-gate 				(void) printf(" %5d %5d",
3090Sstevel@tonic-gate 				    (int)mds.shmx_cpid, (int)mds.shmx_lpid);
3100Sstevel@tonic-gate 			if (tflg) {
3110Sstevel@tonic-gate 				tp(mds.shmx_atime);
3120Sstevel@tonic-gate 				tp(mds.shmx_dtime);
3130Sstevel@tonic-gate 				tp(mds.shmx_ctime);
3140Sstevel@tonic-gate 			}
3150Sstevel@tonic-gate 			if (iflg)
3160Sstevel@tonic-gate 				(void) printf(" %8llu", mds.shmx_cnattch);
3170Sstevel@tonic-gate 			if (Jflg)
3180Sstevel@tonic-gate 				jp(&mds.shmx_perm);
3190Sstevel@tonic-gate 			if (Zflg)
3200Sstevel@tonic-gate 				printzone(mds.shmx_perm.ipcx_zoneid);
3210Sstevel@tonic-gate 			(void) printf("\n");
3220Sstevel@tonic-gate 		}
3230Sstevel@tonic-gate 	}
3240Sstevel@tonic-gate 
3250Sstevel@tonic-gate 	/*
3260Sstevel@tonic-gate 	 * Print Semaphore facility status.
3270Sstevel@tonic-gate 	 */
3280Sstevel@tonic-gate 	if (sflg) {
3290Sstevel@tonic-gate 		struct semid_ds64 sds;
3300Sstevel@tonic-gate 		union semun {
3310Sstevel@tonic-gate 			int val;
3320Sstevel@tonic-gate 			struct semid_ds64 *buf;
3330Sstevel@tonic-gate 			ushort_t *array;
3340Sstevel@tonic-gate 		} semarg;
3350Sstevel@tonic-gate 		semarg.buf = &sds;
3360Sstevel@tonic-gate 
3370Sstevel@tonic-gate 		for (;;) {
3380Sstevel@tonic-gate 			if (semids(ids, nids, &n) != 0) {
3390Sstevel@tonic-gate 				perror("semids");
3400Sstevel@tonic-gate 				exit(1);
3410Sstevel@tonic-gate 			}
3420Sstevel@tonic-gate 			if (n <= nids)
3430Sstevel@tonic-gate 				break;
3440Sstevel@tonic-gate 			ids = realloc(ids, (nids = n) * sizeof (int));
3450Sstevel@tonic-gate 		}
3460Sstevel@tonic-gate 
3470Sstevel@tonic-gate 		if (bflg || tflg || (!qflg && !mflg))
3480Sstevel@tonic-gate 			(void) printf("%s%s%s%s%s%s\n", chdr,
3490Sstevel@tonic-gate 			    cflg ? chdr2 : "",
3500Sstevel@tonic-gate 			    bflg ? " NSEMS" : "",
3510Sstevel@tonic-gate 			    tflg ? "   OTIME    CTIME " : "",
3520Sstevel@tonic-gate 			    Jflg ? chdr3 : "",
3530Sstevel@tonic-gate 			    Zflg ? "     ZONE" : "");
3540Sstevel@tonic-gate 
3550Sstevel@tonic-gate 		(void) printf(gettext("Semaphores:\n"));
3560Sstevel@tonic-gate 
3570Sstevel@tonic-gate 		for (i = 0; i < n; i++) {
3580Sstevel@tonic-gate 			id = ids[i];
3590Sstevel@tonic-gate 			if (semctl64(id, 0, IPC_STAT64, semarg) < 0)
3600Sstevel@tonic-gate 				continue;
3610Sstevel@tonic-gate 			/* ignore zone if -Z was used and -z wasn't */
3620Sstevel@tonic-gate 			if ((zflg || !Zflg) &&
3630Sstevel@tonic-gate 			    sds.semx_perm.ipcx_zoneid != zoneid)
3640Sstevel@tonic-gate 				continue;
3650Sstevel@tonic-gate 			hp('s', "--ra-ra-ra-", &sds.semx_perm, id);
3660Sstevel@tonic-gate 			if (bflg)
3670Sstevel@tonic-gate 				(void) printf(" %5u", sds.semx_nsems);
3680Sstevel@tonic-gate 			if (tflg) {
3690Sstevel@tonic-gate 				tp(sds.semx_otime);
3700Sstevel@tonic-gate 				tp(sds.semx_ctime);
3710Sstevel@tonic-gate 			}
3720Sstevel@tonic-gate 			if (Jflg)
3730Sstevel@tonic-gate 				jp(&sds.semx_perm);
3740Sstevel@tonic-gate 			if (Zflg)
3750Sstevel@tonic-gate 				printzone(sds.semx_perm.ipcx_zoneid);
3760Sstevel@tonic-gate 			(void) printf("\n");
3770Sstevel@tonic-gate 		}
3780Sstevel@tonic-gate 	}
3790Sstevel@tonic-gate 
3800Sstevel@tonic-gate 	return (0);
3810Sstevel@tonic-gate }
3820Sstevel@tonic-gate 
3830Sstevel@tonic-gate /*
3840Sstevel@tonic-gate  * hp - common header print
3850Sstevel@tonic-gate  */
3860Sstevel@tonic-gate static void
hp(char type,char * modesp,struct ipc_perm64 * permp,int slot)3870Sstevel@tonic-gate hp(char type, char *modesp, struct ipc_perm64 *permp, int slot)
3880Sstevel@tonic-gate {
3890Sstevel@tonic-gate 	int		i;	/* loop control */
3900Sstevel@tonic-gate 	struct group	*g;	/* ptr to group group entry */
3910Sstevel@tonic-gate 	struct passwd	*u;	/* ptr to user passwd entry */
3920Sstevel@tonic-gate 	char		keyfield[16];
3930Sstevel@tonic-gate 
394*3797Sceastha 	(void) snprintf(keyfield, sizeof (keyfield), "  0x%x", permp->ipcx_key);
3950Sstevel@tonic-gate 	(void) printf("%c %10d %-13s", type, slot, keyfield);
3960Sstevel@tonic-gate 
3970Sstevel@tonic-gate 	for (i = 02000; i; modesp++, i >>= 1)
3980Sstevel@tonic-gate 		(void) printf("%c", (permp->ipcx_mode & i) ? *modesp : '-');
3990Sstevel@tonic-gate 	if ((u = getpwuid(permp->ipcx_uid)) == NULL)
4000Sstevel@tonic-gate 		(void) printf("%9d", (int)permp->ipcx_uid);
4010Sstevel@tonic-gate 	else
4020Sstevel@tonic-gate 		(void) printf("%9.8s", u->pw_name);
4030Sstevel@tonic-gate 	if ((g = getgrgid(permp->ipcx_gid)) == NULL)
4040Sstevel@tonic-gate 		(void) printf("%9d", (int)permp->ipcx_gid);
4050Sstevel@tonic-gate 	else
4060Sstevel@tonic-gate 		(void) printf("%9.8s", g->gr_name);
4070Sstevel@tonic-gate 
4080Sstevel@tonic-gate 	if (cflg) {
4090Sstevel@tonic-gate 		if ((u = getpwuid(permp->ipcx_cuid)) == NULL)
4100Sstevel@tonic-gate 			(void) printf("%9d", (int)permp->ipcx_cuid);
4110Sstevel@tonic-gate 		else
4120Sstevel@tonic-gate 			(void) printf("%9.8s", u->pw_name);
4130Sstevel@tonic-gate 		if ((g = getgrgid(permp->ipcx_cgid)) == NULL)
4140Sstevel@tonic-gate 			(void) printf("%9d", (int)permp->ipcx_cgid);
4150Sstevel@tonic-gate 		else
4160Sstevel@tonic-gate 			(void) printf("%9.8s", g->gr_name);
4170Sstevel@tonic-gate 	}
4180Sstevel@tonic-gate }
4190Sstevel@tonic-gate 
4200Sstevel@tonic-gate /*
4210Sstevel@tonic-gate  * jp - project header print
4220Sstevel@tonic-gate  */
4230Sstevel@tonic-gate static void
jp(struct ipc_perm64 * permp)4240Sstevel@tonic-gate jp(struct ipc_perm64 *permp)
4250Sstevel@tonic-gate {
4260Sstevel@tonic-gate 	struct project	proj;
4270Sstevel@tonic-gate 	char		buf[PROJECT_BUFSZ];
4280Sstevel@tonic-gate 
4290Sstevel@tonic-gate 	if ((getprojbyid(permp->ipcx_projid, &proj, buf,
4300Sstevel@tonic-gate 	    PROJECT_BUFSZ)) == NULL)
4310Sstevel@tonic-gate 		(void) printf("%16ld", permp->ipcx_projid);
4320Sstevel@tonic-gate 	else
4330Sstevel@tonic-gate 		(void) printf("%16.15s", proj.pj_name);
4340Sstevel@tonic-gate }
4350Sstevel@tonic-gate 
4360Sstevel@tonic-gate /*
4370Sstevel@tonic-gate  * tp - time entry printer
4380Sstevel@tonic-gate  */
4390Sstevel@tonic-gate void
tp(ipc_time_t gmt64)4400Sstevel@tonic-gate tp(ipc_time_t gmt64)
4410Sstevel@tonic-gate {
4420Sstevel@tonic-gate 	struct tm *t;	/* ptr to converted time */
4430Sstevel@tonic-gate 	time_t gmt = (time_t)gmt64;
4440Sstevel@tonic-gate 
4450Sstevel@tonic-gate 	if (gmt && gmt64 <= UINT_MAX) {
4460Sstevel@tonic-gate 		t = localtime(&gmt);
4470Sstevel@tonic-gate 		(void) printf(" %2d:%2.2d:%2.2d",
4480Sstevel@tonic-gate 		    t->tm_hour, t->tm_min, t->tm_sec);
4490Sstevel@tonic-gate 	} else {
4500Sstevel@tonic-gate 		(void) printf("%9s", gettext(" no-entry"));
4510Sstevel@tonic-gate 	}
4520Sstevel@tonic-gate }
4530Sstevel@tonic-gate 
4540Sstevel@tonic-gate /* Round up to a sizeof (size_t) boundary */
4550Sstevel@tonic-gate #define	SZROUND(x)	(((x) + sizeof (size_t) - 1) & ~(sizeof (size_t) - 1))
4560Sstevel@tonic-gate 
4570Sstevel@tonic-gate /*
4580Sstevel@tonic-gate  * dumpmsgq - dump all messages on a message queue
4590Sstevel@tonic-gate  */
4600Sstevel@tonic-gate void
dumpmsgq(int msqid)4610Sstevel@tonic-gate dumpmsgq(int msqid)
4620Sstevel@tonic-gate {
4630Sstevel@tonic-gate 	static struct msgsnap_head *buf = NULL;
4640Sstevel@tonic-gate 	static size_t bufsize;
4650Sstevel@tonic-gate 
4660Sstevel@tonic-gate 	struct msgsnap_mhead *mhead;
4670Sstevel@tonic-gate 	size_t i;
4680Sstevel@tonic-gate 
4690Sstevel@tonic-gate 	/* allocate the minimum required buffer size on first time through */
4700Sstevel@tonic-gate 	if (buf == NULL)
4710Sstevel@tonic-gate 		buf = malloc(bufsize = sizeof (struct msgsnap_head));
4720Sstevel@tonic-gate 
4730Sstevel@tonic-gate 	/*
4740Sstevel@tonic-gate 	 * Fetch all messages specified by mtype from
4750Sstevel@tonic-gate 	 * the queue while leaving the queue intact.
4760Sstevel@tonic-gate 	 */
4770Sstevel@tonic-gate 	for (;;) {
4780Sstevel@tonic-gate 		if (msgsnap(msqid, buf, bufsize, mtype) != 0) {
4790Sstevel@tonic-gate 			/*
4800Sstevel@tonic-gate 			 * Don't complain; either the user does not have
4810Sstevel@tonic-gate 			 * read permission on msqid or msqid was deleted.
4820Sstevel@tonic-gate 			 */
4830Sstevel@tonic-gate 			return;
4840Sstevel@tonic-gate 		}
4850Sstevel@tonic-gate 		if (bufsize >= buf->msgsnap_size) {
4860Sstevel@tonic-gate 			/* we collected all of the messages */
4870Sstevel@tonic-gate 			break;
4880Sstevel@tonic-gate 		}
4890Sstevel@tonic-gate 		/* The buffer is too small; allocate a bigger buffer */
4900Sstevel@tonic-gate 		buf = realloc(buf, bufsize = buf->msgsnap_size);
4910Sstevel@tonic-gate 	}
4920Sstevel@tonic-gate 
4930Sstevel@tonic-gate 	/*
4940Sstevel@tonic-gate 	 * Process each message in the queue (there may be none).
4950Sstevel@tonic-gate 	 * The first message header starts just after the buffer header.
4960Sstevel@tonic-gate 	 */
4970Sstevel@tonic-gate 	mhead = (struct msgsnap_mhead *)(buf + 1);
4980Sstevel@tonic-gate 	for (i = 0; i < buf->msgsnap_nmsg; i++) {
4990Sstevel@tonic-gate 		size_t mlen = mhead->msgsnap_mlen;
5000Sstevel@tonic-gate 
5010Sstevel@tonic-gate 		dumpmsg(mhead->msgsnap_mtype, (char *)(mhead + 1), mlen);
5020Sstevel@tonic-gate 
5030Sstevel@tonic-gate 		/* advance to next message header */
5040Sstevel@tonic-gate 		/* LINTED alignment */
5050Sstevel@tonic-gate 		mhead = (struct msgsnap_mhead *)
506*3797Sceastha 		    ((caddr_t)(mhead + 1) + SZROUND(mlen));
5070Sstevel@tonic-gate 	}
5080Sstevel@tonic-gate }
5090Sstevel@tonic-gate 
5100Sstevel@tonic-gate /*
5110Sstevel@tonic-gate  * dumpmsg - dump one message from a message queue.
5120Sstevel@tonic-gate  */
5130Sstevel@tonic-gate void
dumpmsg(long type,char * msg,size_t msgsize)5140Sstevel@tonic-gate dumpmsg(long type, char *msg, size_t msgsize)
5150Sstevel@tonic-gate {
5160Sstevel@tonic-gate 	size_t i, j, k;
5170Sstevel@tonic-gate 	int c;
5180Sstevel@tonic-gate 
5190Sstevel@tonic-gate 	(void) printf(gettext("  message type %ld, size %lu\n"),
520*3797Sceastha 	    type, (ulong_t)msgsize);
5210Sstevel@tonic-gate 
5220Sstevel@tonic-gate 	for (i = 0; i < msgsize; i += 16) {
5230Sstevel@tonic-gate 		/* first in hex */
5240Sstevel@tonic-gate 		(void) printf(" %5ld:  ", (ulong_t)i);
5250Sstevel@tonic-gate 		for (j = 0; j < 16; j++) {
5260Sstevel@tonic-gate 			if ((k = i + j) < msgsize)
5270Sstevel@tonic-gate 				(void) printf("%2.2x ", msg[k] & 0xff);
5280Sstevel@tonic-gate 			else
5290Sstevel@tonic-gate 				(void) printf("   ");
5300Sstevel@tonic-gate 		}
5310Sstevel@tonic-gate 		/* then in ascii */
5320Sstevel@tonic-gate 		(void) printf("   ");
5330Sstevel@tonic-gate 		for (j = 0; j < 16; j++) {
5340Sstevel@tonic-gate 			if ((k = i + j) >= msgsize)
5350Sstevel@tonic-gate 				break;
5360Sstevel@tonic-gate 			c = msg[k] & 0xff;
5370Sstevel@tonic-gate 			if (isascii(c) && isprint(c))
5380Sstevel@tonic-gate 				(void) printf("%c", c);
5390Sstevel@tonic-gate 			else
5400Sstevel@tonic-gate 				(void) printf(".");
5410Sstevel@tonic-gate 		}
5420Sstevel@tonic-gate 		(void) printf("\n");
5430Sstevel@tonic-gate 	}
5440Sstevel@tonic-gate }
5450Sstevel@tonic-gate 
5460Sstevel@tonic-gate /* convert string containing zone name or id to a numeric id */
5470Sstevel@tonic-gate static zoneid_t
getzone(char * arg)5480Sstevel@tonic-gate getzone(char *arg)
5490Sstevel@tonic-gate {
5500Sstevel@tonic-gate 	zoneid_t zoneid;
5510Sstevel@tonic-gate 
5520Sstevel@tonic-gate 	if (zone_get_id(arg, &zoneid) != 0) {
5530Sstevel@tonic-gate 		(void) fprintf(stderr,
5540Sstevel@tonic-gate 		    gettext("ipcs: unknown zone: %s\n"), arg);
5550Sstevel@tonic-gate 		exit(1);
5560Sstevel@tonic-gate 	}
5570Sstevel@tonic-gate 	return (zoneid);
5580Sstevel@tonic-gate }
5590Sstevel@tonic-gate 
5600Sstevel@tonic-gate static void
printzone(zoneid_t id)5610Sstevel@tonic-gate printzone(zoneid_t id)
5620Sstevel@tonic-gate {
5630Sstevel@tonic-gate 	char zone_name[ZONENAME_MAX];
5640Sstevel@tonic-gate 
5650Sstevel@tonic-gate 	if (getzonenamebyid(id, zone_name, sizeof (zone_name)) < 0)
5660Sstevel@tonic-gate 		(void) printf("%9d", (int)id);
5670Sstevel@tonic-gate 	else
5680Sstevel@tonic-gate 		(void) printf("%9.8s", zone_name);
5690Sstevel@tonic-gate }
570