[alt.sources] shmdump - dump System V shared memory segment

wht@tridom.uucp (Warren Tucker) (12/12/89)

This is a shared memory dump utility for System V.  The compilation
instructions for machines I've tested it on are in the source header
and the usage can be obtained by running the program without arguments. 
This posting is related to a discussion of shared memory currently
ongoing in comp.unix.wizards.

#!/bin/sh
# This is shmdump, a shell archive (shar 3.04)
# made 12/12/1989 07:15 UTC by gatech!kd4nc!n4hgf!wht (wht%n4hgf@gatech.edu)
# Source directory /u1/src/src
#
# existing files will NOT be overwritten
#
# This shar contains:
#    shmdump.c
#
touch 2>&1 | fgrep '[-amc]' > /tmp/s3_touch$$
if [ -s /tmp/s3_touch$$ ]
then
	TOUCH=can
else
	TOUCH=cannot
fi
rm -f /tmp/s3_touch$$
if test -f shmdump.c; then echo "File shmdump.c exists"; else
echo "x - extracting shmdump.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > shmdump.c &&
X/* CHK=0xE884 */
X/*+-------------------------------------------------------------------------
X	shmdump.c
X    ...gatech!kd4nc!n4hgf!wht (free to use as you please)
X
X  Defined functions:
X	hex_dump(str,len)
X	hex_dump16(int16)
X	hex_dump32(int32)
X	hex_dump4(int4)
X	hex_dump8(int8)
X	main(argc,argv,envp)
X	str_to_INT32(str)
X	usage()
X
XSCO XENIX 286: cc -DLINT_ARGS -M2le shmdump.c -o shmdump
XSCO U/X   386: cc -DLINT_ARGS shmdump.c -o shmdump
XISC:           cc shmdump.c -o shmdump
XPyramid:       att cc shmdump.c -o shmdump
X
X--------------------------------------------------------------------------*/
X/*+:EDITS:*/
X/*:12-12-1989-01:50-wht-creation */
X
X#include <stdio.h>
X#include <ctype.h>
X#include <signal.h>
X#include <fcntl.h>
X#include <sys/types.h>
X#include <sys/ipc.h>
X#include <sys/shm.h>
X
X#ifndef UINT8
X#define UINT8	unsigned char
X#define INT8	char
X#define UINT16	unsigned short
X#define INT16	long
X#define UINT32	unsigned long
X#define INT32	long
X#define UINT	unsigned int
X#endif
X
X#if defined(M_I286)
X#define BIGPTR	INT8 far *
X#else
X#define BIGPTR	INT8 *
X#endif
X
X#if defined(LINT_ARGS)
Xint msgctl(int,int,struct msqid_ds *);
Xint msgget(INT32 /* key_t */,int);
Xint msgsnd(int,struct msgbuf *,int,int);
Xint msgrcv(int,struct msgbuf *,int,INT32,int);
Xint semctl(int,int,int,);
Xint semget(INT32 /* key_t */,int,int);
Xint semop(int,struct sembuf *,int);
Xint shmctl(int,int,struct shmid_ds *);
Xint shmget(INT32 /* key_t */,int,int);
XBIGPTR shmat(int,BIGPTR ,int);
Xint shmdt(char *);
X#else
XBIGPTR shmat();
X#endif
X
Xkey_t shmkey;
Xint shmid;
XBIGPTR shmaddr;
X#if !defined(M_I286)
Xint addr32 = 0;
X#endif
X
XBIGPTR sbrk();
X
X/*+-------------------------------------------------------------------------
X	usage()
X--------------------------------------------------------------------------*/
Xvoid
Xusage()
X{
X	fprintf(stderr,"dump shared memory segment\n");
X	fprintf(stderr,"usage: shmdump [-f <offset>] [-l <len>] [-k] <ident>\n");
X	fprintf(stderr,"where <ident> is a shared memory segment id, unless -k\n");
X	fprintf(stderr,"is specified, in which case <ident> is a key.\n");
X	fprintf(stderr,"-f (first), -l (length) allow partial dumps.\n");
X	fprintf(stderr,"numeric params are decimal unless prefixed with '0x'.\n");
X	exit(1);
X}	/* end of usage */
X
X/*+-------------------------------------------------------------------------
X	str_to_INT32(str)
X--------------------------------------------------------------------------*/
XINT32
Xstr_to_INT32(str)
Xchar *str;
X{
X	INT32 ltmp;
X
X	if(!strncmp(str,"0x",2))
X		sscanf(str + 2,"%lx",&ltmp);
X	else
X		sscanf(str,"%ld",&ltmp);
X	return(ltmp);
X
X}	/* end of str_to_INT32 */
X
X/*+-----------------------------------------------------------------------
X	hex_dump#... subservient routines
X------------------------------------------------------------------------*/
X#define dump_putc(ch)		fputc((ch),stdout)
X#define dump_puts(str)		fputs(str,stdout)
Xvoid
Xhex_dump4(int4)
XUINT8 int4;
X{
X	int4 &= 15;
X	dump_putc((int4 >= 10) ? (int4 + 'A' - 10) : (int4 + '0'));
X}
X
Xvoid
Xhex_dump8(int8)
XUINT8 int8;
X{
X	hex_dump4(int8 >> 4);
X	hex_dump4(int8);
X}
X
Xvoid
Xhex_dump16(int16)
XUINT16 int16;
X{
X	hex_dump8(int16 >> 8);
X	hex_dump8(int16);
X}
X
Xvoid
Xhex_dump32(int32)
XUINT32 int32;
X{
X	hex_dump16((UINT16)(int32 >> 16));
X	hex_dump16((UINT16)int32);
X}
X
X/*+-----------------------------------------------------------------
X	hex_dump(str,len,offset)
X------------------------------------------------------------------*/
Xvoid
Xhex_dump(str,len,offset)
XUINT8 *str;
XUINT len;
XUINT offset;
X{
X	register UINT itmp;
X	register UINT istr = 0;
X
X	while(istr < len)
X	{
X#if !defined(M_I286)
X		if(addr32)
X			hex_dump32(istr + offset);
X	else
X#endif
X			hex_dump16(istr + offset);
X
X		if(offset)
X		{
X			dump_putc('(');
X			hex_dump16(offset);
X			dump_putc(')');
X		}
X		dump_putc(' ');
X		for(itmp = 0; itmp < 16; ++itmp)
X		{
X			dump_putc(' ');
X			if(istr + itmp >= len)
X			{
X				dump_putc(' ');
X				dump_putc(' ');
X				continue;
X			}
X			hex_dump8(str[istr + itmp]);
X		}
X		dump_puts(" | ");
X		for(itmp = 0; itmp < 16; ++itmp)
X		{
X			register char dchar;
X			if(istr + itmp >= len)
X				dump_putc(' ');
X			else
X			{
X				dchar = str[istr + itmp] & 0x7F;
X				dump_putc(((dchar >= ' ') && (dchar < 0x7f)) ? dchar : '.' );
X			}
X		}
X		dump_puts(" |\n");
X		istr += 16;
X	}   /* end of while(istr < len) */
X
X}	/* end of hex_dump */
X
X/*+-------------------------------------------------------------------------
X	main(argc,argv,envp)
X--------------------------------------------------------------------------*/
Xmain(argc,argv,envp)
Xint argc;
Xchar **argv;
Xchar **envp;
X{
Xregister UINT first = 0;
Xregister UINT len = 0;
XUINT shmlen;
Xint iargv;
Xint posarg = 0;
Xint key_flag = 0;
XINT32 pos_ltmp;
Xstruct shmid_ds sds;
X
X	if(argc == 1)
X		usage();
X
X	for(iargv = 1; iargv < argc; iargv++)
X	{
X		if(*argv[iargv] == '-')
X		{
X			switch(*(argv[iargv] + 1))
X			{
X			case 'k':	/* pos arg is key, not id */
X				key_flag++;
X				break;
X			case 'f':
X				first = str_to_INT32(argv[iargv] + 2);
X				break;
X			case 'l':
X				len = str_to_INT32(argv[iargv] + 2);
X				break;
X			default:
X				usage();
X			}
X		}
X		else
X		{
X			switch(posarg++)
X			{
X			case 0:
X				pos_ltmp = str_to_INT32(argv[iargv]);
X				break;
X			default:
X				usage();
X			}
X		}
X	}
X
X	if(key_flag)
X	{
X		shmkey = pos_ltmp;
X		if((shmid = shmget(shmkey,0,0)) < 0)
X		{
X			perror("shmget");
X			exit(1);
X		}
X	}
X	else
X		shmid = (int)pos_ltmp;
X
X	if((shmaddr = shmat(shmid,(BIGPTR)0,SHM_RDONLY)) == (BIGPTR)-1)
X	{
X		perror("shmat");
X		exit(1);
X	}
X	if(shmctl(shmid,IPC_STAT,&sds))
X	{
X		perror("shmctl");
X		exit(1);
X	}
X
X	shmkey = sds.shm_perm.key;
X	printf(" id: %d key: %08lx size: %u (%04x) nattach: %d creator pid: %d\n",
X	    shmid,sds.shm_perm.key,sds.shm_segsz,sds.shm_segsz,
X	    sds.shm_nattch - 1,	/* do not include this program */
X		sds.shm_cpid);
X
X	printf(" addresess: attach=%lx, sbrk()=%lx stack=%lx\n",
X		shmaddr,sbrk(0),&argv);
X
X#if !defined(M_I286)
X	if(sds.shm_segsz > 0xFFFF)
X		addr32 = 1;
X#endif
X
X	if(first > (UINT)sds.shm_segsz)
X	{
X		fprintf(stderr,"-f value > size of segment\n");
X		exit(1);
X	}
X	if((len == 0) || (len > (UINT)sds.shm_segsz - first))
X		len = (UINT)sds.shm_segsz - first;
X
X	hex_dump(shmaddr,len,first);
X	exit(0);
X}	/* end of main */
SHAR_EOF
chmod 0644 shmdump.c || echo "restore of shmdump.c fails"
if [ $TOUCH = can ]
then
    touch -m 1212021489 shmdump.c
fi
fi
exit 0
-- 
------------------------------------------------------------------
Warren Tucker, Tridom Corporation      ...!gatech!emory!tridom!wht
home address:                           ...!gatech!kd4nc!n4hgf!wht