xref: /freebsd/usr.bin/ipcs/ipcs.c (revision 4816f94e8af3746740ca49512f196e74640d1cd0)
14816f94eSDoug Rabson /*
24816f94eSDoug Rabson  * Simplified implementation of SYSV ipcs.
34816f94eSDoug Rabson  */
44816f94eSDoug Rabson 
54816f94eSDoug Rabson #include <nlist.h>
64816f94eSDoug Rabson #include <stdio.h>
74816f94eSDoug Rabson #include <stdlib.h>
84816f94eSDoug Rabson #include <unistd.h>
94816f94eSDoug Rabson #include <paths.h>
104816f94eSDoug Rabson 
114816f94eSDoug Rabson #include <sys/time.h>
124816f94eSDoug Rabson #include <sys/types.h>
134816f94eSDoug Rabson #include <sys/param.h>
144816f94eSDoug Rabson #include <sys/proc.h>
154816f94eSDoug Rabson #define KERNEL
164816f94eSDoug Rabson #include <sys/ipc.h>
174816f94eSDoug Rabson #include <sys/sem.h>
184816f94eSDoug Rabson #include <sys/shm.h>
194816f94eSDoug Rabson #include <sys/msg.h>
204816f94eSDoug Rabson 
214816f94eSDoug Rabson #define	SHMSEG_FREE     	0x0200
224816f94eSDoug Rabson #define	SHMSEG_REMOVED  	0x0400
234816f94eSDoug Rabson #define	SHMSEG_ALLOCATED	0x0800
244816f94eSDoug Rabson #define	SHMSEG_WANTED		0x1000
254816f94eSDoug Rabson 
264816f94eSDoug Rabson static kmem_fd;
274816f94eSDoug Rabson 
284816f94eSDoug Rabson getsymbol(struct nlist *symbols, char *symname, void *dptr, int len)
294816f94eSDoug Rabson {
304816f94eSDoug Rabson     int i, rlen;
314816f94eSDoug Rabson 
324816f94eSDoug Rabson     for ( i = 0; symbols[i].n_name != NULL; i += 1 ) {
334816f94eSDoug Rabson 	if ( strcmp(symbols[i].n_name,symname) == 0 ) {
344816f94eSDoug Rabson 	    break;
354816f94eSDoug Rabson 	}
364816f94eSDoug Rabson     }
374816f94eSDoug Rabson 
384816f94eSDoug Rabson     if ( symbols[i].n_name == NULL ) {
394816f94eSDoug Rabson 	fprintf(stderr,"ipcs(getsymbol):  symbol %s not in local symbols list\n",
404816f94eSDoug Rabson 	symname);
414816f94eSDoug Rabson 	exit(1);
424816f94eSDoug Rabson     }
434816f94eSDoug Rabson 
444816f94eSDoug Rabson     if ( symbols[i].n_value == NULL ) {
454816f94eSDoug Rabson 	fprintf(stderr,"ipcs(getsymbol):  symbol %s not in %s\n",
464816f94eSDoug Rabson 	symname,_PATH_UNIX);
474816f94eSDoug Rabson 	return(0);
484816f94eSDoug Rabson     }
494816f94eSDoug Rabson 
504816f94eSDoug Rabson     if ( kmem_fd == 0 ) {
514816f94eSDoug Rabson 	kmem_fd = open("/dev/kmem",0);
524816f94eSDoug Rabson 	if ( kmem_fd < 0 ) {
534816f94eSDoug Rabson 	    perror("ipcs(getsymbol(open /dev/kmem))");
544816f94eSDoug Rabson 	    exit(1);
554816f94eSDoug Rabson 	}
564816f94eSDoug Rabson     }
574816f94eSDoug Rabson 
584816f94eSDoug Rabson     lseek(kmem_fd,symbols[i].n_value,SEEK_SET);
594816f94eSDoug Rabson     if ( (rlen = read(kmem_fd,dptr,len)) != len ) {
604816f94eSDoug Rabson 	fprintf(stderr,"ipcs(getsymbol):  can't fetch symbol %s from /dev/kmem\n",symname);
614816f94eSDoug Rabson 	exit(1);
624816f94eSDoug Rabson     }
634816f94eSDoug Rabson     return(1);
644816f94eSDoug Rabson }
654816f94eSDoug Rabson 
664816f94eSDoug Rabson void
674816f94eSDoug Rabson getlocation(void *addr, void *dptr, int len)
684816f94eSDoug Rabson {
694816f94eSDoug Rabson     int i, rlen;
704816f94eSDoug Rabson 
714816f94eSDoug Rabson     if ( kmem_fd == 0 ) {
724816f94eSDoug Rabson 	kmem_fd = open("/dev/kmem",0);
734816f94eSDoug Rabson 	if ( kmem_fd < 0 ) {
744816f94eSDoug Rabson 	    perror("ipcs(getlocation(open /dev/kmem))");
754816f94eSDoug Rabson 	    exit(1);
764816f94eSDoug Rabson 	}
774816f94eSDoug Rabson     }
784816f94eSDoug Rabson 
794816f94eSDoug Rabson     lseek(kmem_fd,(long)addr,SEEK_SET);
804816f94eSDoug Rabson     if ( (rlen = read(kmem_fd,dptr,len)) != len ) {
814816f94eSDoug Rabson 	fprintf(stderr,"ipcs(getlocation):  can't fetch location %08x from /dev/kmem\n",addr);
824816f94eSDoug Rabson 	exit(1);
834816f94eSDoug Rabson     }
844816f94eSDoug Rabson }
854816f94eSDoug Rabson 
864816f94eSDoug Rabson char *
874816f94eSDoug Rabson fmt_perm(ushort mode)
884816f94eSDoug Rabson {
894816f94eSDoug Rabson     static char buffer[100];
904816f94eSDoug Rabson 
914816f94eSDoug Rabson     buffer[0]  = '-';
924816f94eSDoug Rabson     buffer[1]  = '-';
934816f94eSDoug Rabson     buffer[2]  = ((mode & 0400) ? 'r' : '-');
944816f94eSDoug Rabson     buffer[3]  = ((mode & 0200) ? 'w' : '-');
954816f94eSDoug Rabson     buffer[4]  = ((mode & 0100) ? 'a' : '-');
964816f94eSDoug Rabson     buffer[5]  = ((mode & 0040) ? 'r' : '-');
974816f94eSDoug Rabson     buffer[6]  = ((mode & 0020) ? 'w' : '-');
984816f94eSDoug Rabson     buffer[7]  = ((mode & 0010) ? 'a' : '-');
994816f94eSDoug Rabson     buffer[8]  = ((mode & 0004) ? 'r' : '-');
1004816f94eSDoug Rabson     buffer[9]  = ((mode & 0002) ? 'w' : '-');
1014816f94eSDoug Rabson     buffer[10] = ((mode & 0001) ? 'a' : '-');
1024816f94eSDoug Rabson     buffer[11] = '\0';
1034816f94eSDoug Rabson     return(&buffer[0]);
1044816f94eSDoug Rabson }
1054816f94eSDoug Rabson 
1064816f94eSDoug Rabson void
1074816f94eSDoug Rabson cvt_time(time_t t,char *buf)
1084816f94eSDoug Rabson {
1094816f94eSDoug Rabson     struct tm tms;
1104816f94eSDoug Rabson     static char *months[] = {"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"};
1114816f94eSDoug Rabson     if ( t == 0 ) {
1124816f94eSDoug Rabson 	strcpy(buf,"<not set>");
1134816f94eSDoug Rabson     } else {
1144816f94eSDoug Rabson 	tms = *localtime(&t);
1154816f94eSDoug Rabson 	if ( t > time(0) - 6 * 30 * 24 * 3600 ) {	/* less than about 6 months ago? */
1164816f94eSDoug Rabson 	    sprintf(buf,"%s %2d %2d:%2d",
1174816f94eSDoug Rabson 	    months[tms.tm_mon],tms.tm_mday,tms.tm_hour,tms.tm_min);
1184816f94eSDoug Rabson 	} else {
1194816f94eSDoug Rabson 	    sprintf(buf,"%s %2d %5d",
1204816f94eSDoug Rabson 	    months[tms.tm_mon],tms.tm_mday,tms.tm_year+1900);
1214816f94eSDoug Rabson 	}
1224816f94eSDoug Rabson     }
1234816f94eSDoug Rabson }
1244816f94eSDoug Rabson 
1254816f94eSDoug Rabson main()
1264816f94eSDoug Rabson {
1274816f94eSDoug Rabson     static struct nlist symbols[] = {
1284816f94eSDoug Rabson 	{ "_sema" },
1294816f94eSDoug Rabson 	{ "_seminfo" },
1304816f94eSDoug Rabson 	{ "_semu" },
1314816f94eSDoug Rabson 	{ "_msginfo" },
1324816f94eSDoug Rabson 	{ "_msqids" },
1334816f94eSDoug Rabson 	{ "_shminfo" },
1344816f94eSDoug Rabson 	{ "_shmsegs" },
1354816f94eSDoug Rabson 	{ NULL }
1364816f94eSDoug Rabson     };
1374816f94eSDoug Rabson     int i;
1384816f94eSDoug Rabson     int show_sem_values = 1;
1394816f94eSDoug Rabson     int show_undo_values = 1;
1404816f94eSDoug Rabson 
1414816f94eSDoug Rabson     switch ( nlist(_PATH_UNIX,&symbols[0]) ) {
1424816f94eSDoug Rabson     case 0: break;
1434816f94eSDoug Rabson     case -1:
1444816f94eSDoug Rabson 	fprintf(stderr,"ipcs:  can't open %s - bye!\n",_PATH_UNIX);
1454816f94eSDoug Rabson 	exit(1);
1464816f94eSDoug Rabson     default:
1474816f94eSDoug Rabson 	fprintf(stderr,"ipcs:  nlist failed\n");
1484816f94eSDoug Rabson 	for ( i = 0; symbols[i].n_name != NULL; i += 1 ) {
1494816f94eSDoug Rabson 	    if ( symbols[i].n_value == 0 ) {
1504816f94eSDoug Rabson 		fprintf(stderr,"\tsymbol %s not found\n",symbols[i].n_name);
1514816f94eSDoug Rabson 	    }
1524816f94eSDoug Rabson 	}
1534816f94eSDoug Rabson 	break;
1544816f94eSDoug Rabson     }
1554816f94eSDoug Rabson 
1564816f94eSDoug Rabson     /*
1574816f94eSDoug Rabson     for ( i = 0; symbols[i].n_name != NULL; i += 1 ) {
1584816f94eSDoug Rabson 	fprintf(stderr,"\t%s : %08x\n",symbols[i].n_name,symbols[i].n_value);
1594816f94eSDoug Rabson     }
1604816f94eSDoug Rabson     */
1614816f94eSDoug Rabson 
1624816f94eSDoug Rabson     if ( getsymbol(symbols,"_shminfo",&shminfo,sizeof(shminfo)) ) {
1634816f94eSDoug Rabson 	struct shmid_ds* xshm;
1644816f94eSDoug Rabson struct shminfo {
1654816f94eSDoug Rabson 	int	shmmax,		/* max shared memory segment size (bytes) */
1664816f94eSDoug Rabson 		shmmin,		/* min shared memory segment size (bytes) */
1674816f94eSDoug Rabson 		shmmni,		/* max number of shared memory identifiers */
1684816f94eSDoug Rabson 		shmseg,		/* max shared memory segments per process */
1694816f94eSDoug Rabson 		shmall;		/* max amount of shared memory (pages) */
1704816f94eSDoug Rabson };
1714816f94eSDoug Rabson 	printf("shminfo:\n");
1724816f94eSDoug Rabson 	    printf("\tshmmax: %6d\t(max size of a shared memory segment)\n", shminfo.shmmax);
1734816f94eSDoug Rabson 	    printf("\tshmmin: %6d\t(min size of a shared memory segment)\n", shminfo.shmmin);
1744816f94eSDoug Rabson 	    printf("\tshmmni: %6d\t(max # of shared memory segments)\n", shminfo.shmmni);
1754816f94eSDoug Rabson 	    printf("\tshmseg: %6d\t(max # of shared memory segments per process)\n", shminfo.shmseg);
1764816f94eSDoug Rabson 	    printf("\tshmall: %6d\t(# of shared memory pages available)\n", shminfo.shmall);
1774816f94eSDoug Rabson 
1784816f94eSDoug Rabson 	getsymbol(symbols, "_shmsegs", &shmsegs, sizeof(shmsegs));
1794816f94eSDoug Rabson 	xshm = malloc(sizeof(struct shmid_ds) * shminfo.shmmni);
1804816f94eSDoug Rabson 	getlocation(shmsegs,xshm,sizeof(struct shmid_ds) * shminfo.shmmni);
1814816f94eSDoug Rabson 	for ( i = 0; i < shminfo.shmmni; i += 1 ) {
1824816f94eSDoug Rabson 	    if ( (xshm[i].shm_perm.mode & SHMSEG_ALLOCATED) != 0 ) {
1834816f94eSDoug Rabson 		char ctime_buf[100], atime_buf[100];
1844816f94eSDoug Rabson 		struct shmid_ds* shmaptr = &xshm[i];
1854816f94eSDoug Rabson 		cvt_time(shmaptr->shm_ctime,ctime_buf);
1864816f94eSDoug Rabson 		cvt_time(shmaptr->shm_atime,atime_buf);
1874816f94eSDoug Rabson 
1884816f94eSDoug Rabson 		printf("\nshma id:  %d  key:  0x%08x:\n",
1894816f94eSDoug Rabson 		IXSEQ_TO_IPCID(i,shmaptr->shm_perm),
1904816f94eSDoug Rabson 		shmaptr->shm_perm.key);
1914816f94eSDoug Rabson 
1924816f94eSDoug Rabson 		printf("     cuid:  %6d    cgid:  %6d    ctime:  %s\n",
1934816f94eSDoug Rabson 		shmaptr->shm_perm.cuid,shmaptr->shm_perm.cgid,ctime_buf);
1944816f94eSDoug Rabson 
1954816f94eSDoug Rabson 		printf("     uid:   %6d    gid:   %6d    atime:  %s\n",
1964816f94eSDoug Rabson 		shmaptr->shm_perm.uid,shmaptr->shm_perm.gid,atime_buf);
1974816f94eSDoug Rabson 
1984816f94eSDoug Rabson 		printf("     size:  %6d    attach:%6d     perm:   %s\n",
1994816f94eSDoug Rabson 		shmaptr->shm_segsz,shmaptr->shm_nattch,fmt_perm(shmaptr->shm_perm.mode));
2004816f94eSDoug Rabson 	    }
2014816f94eSDoug Rabson 	}
2024816f94eSDoug Rabson     }
2034816f94eSDoug Rabson 
2044816f94eSDoug Rabson     if ( getsymbol(symbols,"_seminfo",&seminfo,sizeof(seminfo)) ) {
2054816f94eSDoug Rabson 	struct semid_ds *xsema;
2064816f94eSDoug Rabson 
2074816f94eSDoug Rabson 	printf("\nseminfo:\n");
2084816f94eSDoug Rabson 	    printf("\tsemmap: %6d\t(# of entries in semaphore map)\n",seminfo.semmap);
2094816f94eSDoug Rabson 	    printf("\tsemmni: %6d\t(# of semaphore identifiers)\n",seminfo.semmni);
2104816f94eSDoug Rabson 	    printf("\tsemmns: %6d\t(# of semaphores in system)\n",seminfo.semmns);
2114816f94eSDoug Rabson 	    printf("\tsemmnu: %6d\t(# of undo structures in system)\n",seminfo.semmnu);
2124816f94eSDoug Rabson 	    printf("\tsemmsl: %6d\t(max # of semaphores per id)\n",seminfo.semmsl);
2134816f94eSDoug Rabson 	    printf("\tsemopm: %6d\t(max # of operations per semop call)\n",seminfo.semopm);
2144816f94eSDoug Rabson 	    printf("\tsemume: %6d\t(max # of undo entries per process)\n",seminfo.semume);
2154816f94eSDoug Rabson 	    printf("\tsemusz: %6d\t(size in bytes of undo structure)\n",seminfo.semusz);
2164816f94eSDoug Rabson 	    printf("\tsemvmx: %6d\t(semaphore maximum value)\n",seminfo.semvmx);
2174816f94eSDoug Rabson 	    printf("\tsemaem: %6d\t(adjust on exit max value)\n",seminfo.semaem);
2184816f94eSDoug Rabson 
2194816f94eSDoug Rabson 	/*
2204816f94eSDoug Rabson 	 * Lock out other users of the semaphore facility
2214816f94eSDoug Rabson 	 */
2224816f94eSDoug Rabson 
2234816f94eSDoug Rabson 	if ( semconfig(SEM_CONFIG_FREEZE) != 0 ) {
2244816f94eSDoug Rabson 	    perror("semconfig");
2254816f94eSDoug Rabson 	    fprintf(stderr,"Can't lock semaphore facility - winging it...\n");
2264816f94eSDoug Rabson 	}
2274816f94eSDoug Rabson 
2284816f94eSDoug Rabson 	getsymbol(symbols,"_sema",&sema,sizeof(sema));
2294816f94eSDoug Rabson 	xsema = malloc(sizeof(struct semid_ds) * seminfo.semmni);
2304816f94eSDoug Rabson 	getlocation(sema,xsema,sizeof(struct semid_ds) * seminfo.semmni);
2314816f94eSDoug Rabson 
2324816f94eSDoug Rabson 	for ( i = 0; i < seminfo.semmni; i += 1 ) {
2334816f94eSDoug Rabson 	    if ( (xsema[i].sem_perm.mode & SEM_ALLOC) != 0 ) {
2344816f94eSDoug Rabson 		char ctime_buf[100], otime_buf[100];
2354816f94eSDoug Rabson 		struct semid_ds *semaptr = &xsema[i];
2364816f94eSDoug Rabson 		cvt_time(semaptr->sem_ctime,ctime_buf);
2374816f94eSDoug Rabson 		cvt_time(semaptr->sem_otime,otime_buf);
2384816f94eSDoug Rabson 
2394816f94eSDoug Rabson 		printf("\nsema id:  %d  key:  0x%08x:\n",
2404816f94eSDoug Rabson 		IXSEQ_TO_IPCID(i,semaptr->sem_perm),
2414816f94eSDoug Rabson 		semaptr->sem_perm.key);
2424816f94eSDoug Rabson 
2434816f94eSDoug Rabson 		printf("     cuid:  %6d    cgid:  %6d    ctime:  %s\n",
2444816f94eSDoug Rabson 		semaptr->sem_perm.cuid,semaptr->sem_perm.cgid,ctime_buf);
2454816f94eSDoug Rabson 
2464816f94eSDoug Rabson 		printf("     uid:   %6d    gid:   %6d    otime:  %s\n",
2474816f94eSDoug Rabson 		semaptr->sem_perm.uid,semaptr->sem_perm.gid,otime_buf);
2484816f94eSDoug Rabson 
2494816f94eSDoug Rabson 		printf("     nsems: %6d                     perm:   %s\n",
2504816f94eSDoug Rabson 		semaptr->sem_nsems,fmt_perm(semaptr->sem_perm.mode));
2514816f94eSDoug Rabson 
2524816f94eSDoug Rabson 		if ( show_sem_values ) {
2534816f94eSDoug Rabson 		    int j, value;
2544816f94eSDoug Rabson 		    union semun junk;
2554816f94eSDoug Rabson 		    for ( j = 0; j < semaptr->sem_nsems; j += 1 ) {
2564816f94eSDoug Rabson 			if ( (value = semctl( IXSEQ_TO_IPCID(i,semaptr->sem_perm), j, GETVAL, junk )) < 0 ) {
2574816f94eSDoug Rabson 			    printf("can't get semaphore values\n");
2584816f94eSDoug Rabson 			    break;
2594816f94eSDoug Rabson 			}
2604816f94eSDoug Rabson 			if ( j % 5 == 0 ) {
2614816f94eSDoug Rabson 			    if ( j == 0 ) {
2624816f94eSDoug Rabson 				printf("     values: {");
2634816f94eSDoug Rabson 			    } else {
2644816f94eSDoug Rabson 				printf("\n");
2654816f94eSDoug Rabson 				printf("              ");
2664816f94eSDoug Rabson 			    }
2674816f94eSDoug Rabson 			}
2684816f94eSDoug Rabson 			printf(" %d",value);
2694816f94eSDoug Rabson 			if ( j == semaptr->sem_nsems - 1 ) {
2704816f94eSDoug Rabson 			    printf(" }\n");
2714816f94eSDoug Rabson 			} else {
2724816f94eSDoug Rabson 			    printf(", ");
2734816f94eSDoug Rabson 			}
2744816f94eSDoug Rabson 		    }
2754816f94eSDoug Rabson 		}
2764816f94eSDoug Rabson 
2774816f94eSDoug Rabson 	    }
2784816f94eSDoug Rabson 
2794816f94eSDoug Rabson 	}
2804816f94eSDoug Rabson 
2814816f94eSDoug Rabson 	if ( show_undo_values ) {
2824816f94eSDoug Rabson 	    int j;
2834816f94eSDoug Rabson 	    int *ksemu, *semu;
2844816f94eSDoug Rabson 	    int semu_size;
2854816f94eSDoug Rabson 	    int got_one_undo = 0;
2864816f94eSDoug Rabson 
2874816f94eSDoug Rabson 	    semu = 0;
2884816f94eSDoug Rabson 	    semu_size = (int)SEMU(seminfo.semmnu);
2894816f94eSDoug Rabson 	    semu = (int *)malloc( semu_size );
2904816f94eSDoug Rabson 	    getsymbol(symbols,"_semu",&ksemu,sizeof(ksemu));
2914816f94eSDoug Rabson 	    getlocation(ksemu,semu,semu_size);
2924816f94eSDoug Rabson 
2934816f94eSDoug Rabson 	    printf("\nsem undos:\n");
2944816f94eSDoug Rabson 	    for ( j = 0; j < seminfo.semmnu; j += 1 ) {
2954816f94eSDoug Rabson 		struct sem_undo *suptr;
2964816f94eSDoug Rabson 		int k;
2974816f94eSDoug Rabson 
2984816f94eSDoug Rabson 		suptr = SEMU(j);
2994816f94eSDoug Rabson 		if ( suptr->un_proc != NULL ) {
3004816f94eSDoug Rabson 		    struct proc proc;
3014816f94eSDoug Rabson 		    getlocation(suptr->un_proc,&proc,sizeof(proc));
3024816f94eSDoug Rabson 		    got_one_undo = 1;
3034816f94eSDoug Rabson 		    printf("     pid %d:  semid  semnum  adjval\n",proc.p_pid);
3044816f94eSDoug Rabson 		    for ( k = 0; k < suptr->un_cnt; k += 1 ) {
3054816f94eSDoug Rabson 			printf("          %10d   %5d  %6d\n",
3064816f94eSDoug Rabson 			IXSEQ_TO_IPCID(suptr->un_ent[k].un_id,xsema[suptr->un_ent[k].un_id].sem_perm),
3074816f94eSDoug Rabson 			suptr->un_ent[k].un_num,
3084816f94eSDoug Rabson 			suptr->un_ent[k].un_adjval);
3094816f94eSDoug Rabson 		    }
3104816f94eSDoug Rabson 		}
3114816f94eSDoug Rabson 	    }
3124816f94eSDoug Rabson 	    if ( !got_one_undo ) {
3134816f94eSDoug Rabson 		printf("     none allocated\n");
3144816f94eSDoug Rabson 	    }
3154816f94eSDoug Rabson 	}
3164816f94eSDoug Rabson 
3174816f94eSDoug Rabson 	(void)semconfig(SEM_CONFIG_THAW);
3184816f94eSDoug Rabson 
3194816f94eSDoug Rabson     } else {
3204816f94eSDoug Rabson 	fprintf(stderr,"SVID semaphores facility not configured in the system\n");
3214816f94eSDoug Rabson     }
3224816f94eSDoug Rabson 
3234816f94eSDoug Rabson     if ( getsymbol(symbols,"_msginfo",&msginfo,sizeof(msginfo)) ) {
3244816f94eSDoug Rabson 	struct msqid_ds *xmsqids;
3254816f94eSDoug Rabson 
3264816f94eSDoug Rabson 	printf("\nmsginfo:\n");
3274816f94eSDoug Rabson 	    printf("\tmsgmax: %6d\t(max characters in a message)\n",msginfo.msgmax);
3284816f94eSDoug Rabson 	    printf("\tmsgmni: %6d\t(# of message queues)\n",msginfo.msgmni);
3294816f94eSDoug Rabson 	    printf("\tmsgmnb: %6d\t(max characters in a message queue)\n",msginfo.msgmnb);
3304816f94eSDoug Rabson 	    printf("\tmsgtql: %6d\t(max # of messages in system)\n",msginfo.msgtql);
3314816f94eSDoug Rabson 	    printf("\tmsgssz: %6d\t(size of a message segment)\n",msginfo.msgssz);
3324816f94eSDoug Rabson 	    printf("\tmsgseg: %6d\t(# of message segments in system)\n",msginfo.msgseg);
3334816f94eSDoug Rabson 
3344816f94eSDoug Rabson 	getsymbol(symbols,"_msqids",&msqids,sizeof(msqids));
3354816f94eSDoug Rabson 	xmsqids = malloc(sizeof(struct msqid_ds) * msginfo.msgmni);
3364816f94eSDoug Rabson 	getlocation(msqids,xmsqids,sizeof(struct msqid_ds) * msginfo.msgmni);
3374816f94eSDoug Rabson 
3384816f94eSDoug Rabson 	for ( i = 0; i < msginfo.msgmni; i += 1 ) {
3394816f94eSDoug Rabson 	    if ( xmsqids[i].msg_qbytes != 0 ) {
3404816f94eSDoug Rabson 		char stime_buf[100], rtime_buf[100], ctime_buf[100];
3414816f94eSDoug Rabson 		struct msqid_ds *msqptr = &xmsqids[i];
3424816f94eSDoug Rabson 
3434816f94eSDoug Rabson 		cvt_time(msqptr->msg_stime,stime_buf);
3444816f94eSDoug Rabson 		cvt_time(msqptr->msg_rtime,rtime_buf);
3454816f94eSDoug Rabson 		cvt_time(msqptr->msg_ctime,ctime_buf);
3464816f94eSDoug Rabson 
3474816f94eSDoug Rabson 		printf("\nmsgq id:  %d  key:  0x%08x\n",
3484816f94eSDoug Rabson 		IXSEQ_TO_IPCID(i,msqptr->msg_perm),
3494816f94eSDoug Rabson 		msqptr->msg_perm.key);
3504816f94eSDoug Rabson 
3514816f94eSDoug Rabson 		printf("     cuid:  %6d    cgid:  %6d    ctime:  %s\n",
3524816f94eSDoug Rabson 		msqptr->msg_perm.cuid,msqptr->msg_perm.cgid,ctime_buf);
3534816f94eSDoug Rabson 
3544816f94eSDoug Rabson 		printf("     uid:   %6d    gid:   %6d\n",
3554816f94eSDoug Rabson 		msqptr->msg_perm.uid,msqptr->msg_perm.gid);
3564816f94eSDoug Rabson 
3574816f94eSDoug Rabson 		printf("     lspid: %6d                     stime:  %s\n",
3584816f94eSDoug Rabson 		msqptr->msg_lspid,stime_buf);
3594816f94eSDoug Rabson 
3604816f94eSDoug Rabson 		printf("     lrpid: %6d    qnum:  %6d    rtime:  %s\n",
3614816f94eSDoug Rabson 		msqptr->msg_lrpid,msqptr->msg_qnum,rtime_buf);
3624816f94eSDoug Rabson 
3634816f94eSDoug Rabson 		printf("     cbytes:%6d    qbytes:%6d    perm:   %s\n",
3644816f94eSDoug Rabson 		msqptr->msg_cbytes,msqptr->msg_qbytes,fmt_perm(msqptr->msg_perm.mode));
3654816f94eSDoug Rabson 
3664816f94eSDoug Rabson 	    }
3674816f94eSDoug Rabson 	}
3684816f94eSDoug Rabson 
3694816f94eSDoug Rabson     } else {
3704816f94eSDoug Rabson 	fprintf(stderr,"SVID messages facility not configured in the system\n");
3714816f94eSDoug Rabson     }
3724816f94eSDoug Rabson 
3734816f94eSDoug Rabson     exit(0);
3744816f94eSDoug Rabson }
375