PUTDENV for DeSmet 'C', more portable
Bernie Roehl
broehl at watale.UUCP
Sat Aug 30 11:48:54 AEST 1986
Here is the PUTDENV code for DeSmet 'C'. It would be a little easier to port
to another compiler than the MicroSoft 'C' code. Ignore the include of SYS.H
That file is not needed. Have Fun!!!!
# This is a shell archive. Remove anything before this line,
# then unpack it by saving it in a file and typing "sh file".
#
# Wrapped by watale!broehl on Fri Aug 29 21:46:25 EDT 1986
# Contents: peekb.a peekw.a pokeb.a pokew.a putdenv.c
echo x - peekb.a
sed 's/^@//' > "peekb.a" <<'@//E*O*F peekb.a//'
;/* Written by Bernie Roehl at watdcsu.uucp, July 1986 */
; peekb(offset, segment)
;
cseg
public peekb_
peekb_:
push bp
mov bp,sp
mov bx,[bp+4]
mov es,[bp+6]
mov al,es:[bx]
xor ah,ah
pop bp
ret
@//E*O*F peekb.a//
chmod u=rw,g=r,o=r peekb.a
echo x - peekw.a
sed 's/^@//' > "peekw.a" <<'@//E*O*F peekw.a//'
;/* Written by Bernie Roehl at watdcsu.uucp, July 1986 */
; peekw(offset, segment)
;
cseg
public peekw_
peekw_:
push bp
mov bp,sp
mov bx,[bp+4]
mov es,[bp+6]
mov ax,es:[bx]
pop bp
ret
@//E*O*F peekw.a//
chmod u=rw,g=r,o=r peekw.a
echo x - pokeb.a
sed 's/^@//' > "pokeb.a" <<'@//E*O*F pokeb.a//'
;/* Written by Bernie Roehl at watdcsu.uucp, July 1986 */
; pokeb(val, offset, segment)
;
cseg
public pokeb_
pokeb_:
push bp
mov bp,sp
mov ax,[bp+4]
mov bx,[bp+6]
mov es,[bp+8]
mov es:[bx],al
pop bp
ret
@//E*O*F pokeb.a//
chmod u=rw,g=r,o=r pokeb.a
echo x - pokew.a
sed 's/^@//' > "pokew.a" <<'@//E*O*F pokew.a//'
;/* Written by Bernie Roehl at watdcsu.uucp, July 1986 */
; pokew(val, offset, segment)
;
cseg
public pokew_
pokew_:
push bp
mov bp,sp
mov ax,[bp+4]
mov bx,[bp+6]
mov es,[bp+8]
mov es:[bx],ax
pop bp
ret
@//E*O*F pokew.a//
chmod u=rw,g=r,o=r pokew.a
echo x - putdenv.c
sed 's/^@//' > "putdenv.c" <<'@//E*O*F putdenv.c//'
/* Set an environment variable */
/* Written by Bernie Roehl at watdcsu.uucp, July 1986 */
#include <stdio.h>
#include <sys.h>
static unsigned orig_env;
static unsigned orig_size;
static match(s, p, env)
char *s, *p; unsigned env;
{
while (peekb(p, env)) {
if (*s != peekb(p++, env))
return 0; /* mismatch ! */
if (*s++ == '=') /* hit the = sign */
return 1; /* match up to = */
}
return *s == '\0'; /* if *s is also null, match => return 1 */
}
static nextenv(s)
char *s;
{
while (peekb(s++, orig_env))
;
return s;
}
static find_orig()
{
unsigned psp, header;
psp = _showcs() - 0x10;
while (psp != peekw(0x0C, psp))
psp = peekw(0x0C, psp);
/* we now take advantage of the undocumented structure of MSDOS
memory allocation blocks */
header = psp - 1; /* the paragraph *before* an allocated block is a header */
if (peekb(0, header) != 'M') /* something's wrong, somewhere */
return -1;
if (peekw(1, header) != psp) /* something else is wrong, somewhere */
return -2;
/* Really arcane magic: address of oldest psp, plus its size, plus 1,
happens to point to the DOS environment. I sense evil spirits... */
orig_env = peekw(1, header) + peekw(3, header) + 1;
header = orig_env - 1; /* get its memory allocation block */
if (peekb(0, header) != 'M') /* something's wrong, somewhere */
return -3;
orig_size = peekw(3, header); /* and get the environment size from it */
return 0; /* all is well with the world */
}
static set_var(s)
char *s;
{
char *p, *src;
for (p = 0; peekb(p, orig_env); p = nextenv(p, orig_env))
if (match(s, p, orig_env))
break;
if (peekb(p, orig_env)) { /* it was there; p points to it */
if (peekb(src = nextenv(p, orig_env), orig_env)) { /* there's stuff after it */
while (peekb(src, orig_env) || peekb(src + 1, orig_env))
pokeb(peekb(src++, orig_env), p++, orig_env);
pokeb('\0', p++, orig_env);
}
/* else p points to the last envvar, which is we;re losing anyway */
}
/* p now points to the end of the living environment */
/* the inner + 2 below may not be necessary, but why take the chance? */
if ((p + strlen(s) + 2) / 16 + 1 >= orig_size)
return -1; /* no room */
if (src = index(s, '=')) /* is there an '=' in it? */
if (src[1] == '\0') { /* is there nothing after it? (i.e. XYZ= ) */
pokeb('\0', p++, orig_env); /* terminate the string */
pokeb('\0', p++, orig_env); /* and the environment */
return 0; /* string deleted okay */
}
while (*s)
pokeb(*s++, p++, orig_env);
pokeb('\0', p++, orig_env); /* terminate the string */
pokeb('\0', p++, orig_env); /* and the environment */
return 0; /* string added */
}
putdenv(s)
char *s;
{
if (find_orig()) /* find the original environment */
return -1;
return set_var(s);
}
/* For the record, an MSDOS memory block header looks like this: */
struct _mb {
char flag; /* M for normal, Z for last one */
unsigned owner; /* Segment address of owner's PSP */
unsigned size; /* size of the block in paragraphs */
};
@//E*O*F putdenv.c//
chmod u=rw,g=r,o=r putdenv.c
echo Inspecting for damage in transit...
temp=/tmp/shar$$; dtemp=/tmp/.shar$$
trap "rm -f $temp $dtemp; exit" 0 1 2 3 15
cat > $temp <<\!!!
14 31 202 peekb.a
13 29 191 peekw.a
14 32 211 pokeb.a
14 32 211 pokew.a
106 525 3055 putdenv.c
161 649 3870 total
!!!
wc peekb.a peekw.a pokeb.a pokew.a putdenv.c | sed 's=[^ ]*/==' | diff -b $temp - >$dtemp
if [ -s $dtemp ]
then echo "Ouch [diff of wc output]:" ; cat $dtemp
else echo "No problems found."
fi
exit 0
--
Michael A. Shiels
clyde-\
decvax-\\
ihnp4-\\\
+++-----> watmath!watale!broehl
tektronix-///
ubc-vision-//
utzoo-/
More information about the Comp.sources.unix
mailing list