Article 12783 of alt.sources:
Path: nntpd.lkg.dec.com!crl.dec.com!crl.dec.com!caen!uwm.edu!fnnews.fnal.gov!watson.math.niu.edu!mp.cs.niu.edu!vixen.cso.uiuc.edu!howland.reston.ans.net!agate!news.mindlink.net!van-bc!vanbc.wimsey.com!not-for-mail
From: markh@vanbc.wimsey.com (Mark C. Henderson)
Newsgroups: alt.sources
Subject: change sun hostid 1.5.0 -- part 2/4
Date: 8 Sep 1995 09:15:30 -0700
Organization: Online at Wimsey Information Services Inc - Vancouver, Canada
Lines: 1670
Message-ID: <42pq72$lo9@vanbc.wimsey.com>
NNTP-Posting-Host: vanbc.wimsey.com


#!/bin/sh
# This is `hid150.02' (part 2 of a multipart archive).
# Do not concatenate these parts, unpack them in order with `/bin/sh'.
# File `hid-1.5.0/hid_solaris2.c' is being continued...
#
touch -am 1231235999 $$.touch >/dev/null 2>&1
if test ! -f 1231235999 && test -f $$.touch; then
  shar_touch=touch
else
  shar_touch=:
  echo
  echo 'WARNING: not restoring timestamps.  Consider getting and'
  echo "installing GNU \`touch', distributed in GNU File Utilities..."
  echo
fi
rm -f 1231235999 $$.touch
#
if test ! -r _sharseq.tmp; then
  echo 'Please unpack part 1 first!'
  exit 1
fi
shar_sequence=`cat _sharseq.tmp`
if test "$shar_sequence" != 2; then
  echo "Please unpack part $shar_sequence next!"
  exit 1
fi
if test ! -f _sharnew.tmp; then
  echo 'x - still skipping hid-1.5.0/hid_solaris2.c'
else
  echo 'x - continuing file hid-1.5.0/hid_solaris2.c'
  sed 's/^X//' << 'SHAR_EOF' >> 'hid-1.5.0/hid_solaris2.c' &&
and licence keys cannot be obtained quickly from the vendor. Many
vendors will not supply licence keys outside of business hours.
X
The hostid is stored in ASCII decimal form in the kernel variable
hw_serial. We simply change the in-core value of the string pointed
to by hw_serial.
X
*/
X
#include <stdio.h>
main(argc,argv)
int argc;
char *argv[];
{
X    unsigned int hid;
X    int i;
X    char obuf[15];
X    for (i=0; i<15; i++)
X        obuf[i] = '\0';
X
X    if (argc != 2) {
X        fprintf(stderr, "usage: %s hostid\n",argv[0]);
X        exit(1);
X    }
X    sscanf(argv[1],"%08x",&hid);
X    sprintf(obuf,"%u", hid);  /* should this be %010u ? */
X
X    printf("#!/bin/sh\n");
X    printf("# this script sets the hostid to %08x\n",hid);
X    printf("adb -w -k /kernel/unix /dev/mem <<END\n");
X    printf("hw_serial/W 0x");
X    for (i=0; i<4; i++)
X        printf("%02x", obuf[i]);
X    printf("\n");
X    printf("hw_serial+4/W 0x");
X    for (; i<8; i++)
X        printf("%02x", obuf[i]);
X    printf("\n");
X    printf("hw_serial+8/W 0x");
X    for (; i<12; i++)
X        printf("%02x", obuf[i]);
X    printf("\n");
X    printf("END\n");
}
SHAR_EOF
  echo 'File hid-1.5.0/hid_solaris2.c is complete' &&
  $shar_touch -am 0626235695 'hid-1.5.0/hid_solaris2.c' &&
  chmod 0600 'hid-1.5.0/hid_solaris2.c' ||
  echo 'restore of hid-1.5.0/hid_solaris2.c failed'
  shar_count="`wc -c < 'hid-1.5.0/hid_solaris2.c'`"
  test 2059 -eq "$shar_count" ||
    echo "hid-1.5.0/hid_solaris2.c: original size 2059, current size $shar_count"
  rm -f _sharnew.tmp
fi
# ============= hid-1.5.0/hid_solaris2x86.c ==============
if test -f 'hid-1.5.0/hid_solaris2x86.c' && test X"$1" != X"-c"; then
  echo 'x - skipping hid-1.5.0/hid_solaris2x86.c (file already exists)'
  rm -f _sharnew.tmp
else
  > _sharnew.tmp
  echo 'x - extracting hid-1.5.0/hid_solaris2x86.c (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'hid-1.5.0/hid_solaris2x86.c' &&
/* change the hostid reported by sysinfo and gethostid on Solaris 2.4 x86
X   - run the script this produces on stdout to actually make the change. Note
X     that you must have adb installed to use this 
X
X    e.g. hid_solaris2 b0b1fb0b | sh -v
X
Mark Henderson <markh@wimsey.bc.ca>
Placed in the public domain by the author - June 1995
X 
This program is distributed in the hope that it will be useful,
but without any warranty; without even the implied warranty of
merchantability or fitness for a particular purpose. You use
this program at your own risk. The author disclaims responsibility for
any damages that might result from the use of this program, even
if they result from negligence on the part of the author.
X
Also, please don't use this program to steal software. The intended
use is for emergency situations where an application has to be moved from
one computer to another (e.g. in the event of a hardware malfunction)
and licence keys cannot be obtained quickly from the vendor. Many
vendors will not supply licence keys outside of business hours.
X
The hostid is stored in ASCII decimal form in the kernel variable
hw_serial. We simply change the in-core value of the string pointed
to by hw_serial.
X
*/
X
#include <stdio.h>
main(argc,argv)
int argc;
char *argv[];
{
X    unsigned int hid;
X    int i;
X    char obuf[15];
X    for (i=0; i<15; i++)
X        obuf[i] = '\0';
X
X    if (argc != 2) {
X        fprintf(stderr, "usage: %s hostid\n",argv[0]);
X        exit(1);
X    }
X    sscanf(argv[1],"%08x",&hid);
X    sprintf(obuf,"%u", hid);  /* should this be %010u ? */
X
X    printf("#!/bin/sh\n");
X    printf("# this script sets the hostid to %08x\n",hid);
X    printf("adb -w -k /kernel/unix /dev/mem <<END\n");
X    printf("hw_serial/W 0x");
X    for (i=3; i>=0; i--)
X        printf("%02x", obuf[i]);
X    printf("\n");
X    printf("hw_serial+4/W 0x");
X    for (i=7; i>=4; i--)
X        printf("%02x", obuf[i]);
X    printf("\n");
X    printf("hw_serial+8/W 0x");
X    for (i=11; i>=8; i--)
X        printf("%02x", obuf[i]);
X    printf("\n");
X    printf("END\n");
}
SHAR_EOF
  $shar_touch -am 0626235595 'hid-1.5.0/hid_solaris2x86.c' &&
  chmod 0600 'hid-1.5.0/hid_solaris2x86.c' ||
  echo 'restore of hid-1.5.0/hid_solaris2x86.c failed'
  shar_count="`wc -c < 'hid-1.5.0/hid_solaris2x86.c'`"
  test 2060 -eq "$shar_count" ||
    echo "hid-1.5.0/hid_solaris2x86.c: original size 2060, current size $shar_count"
  rm -f _sharnew.tmp
fi
# ============= hid-1.5.0/hostid-by-egid-modload/README ==============
if test ! -d 'hid-1.5.0/hostid-by-egid-modload'; then
  echo 'x - creating directory hid-1.5.0/hostid-by-egid-modload'
  mkdir 'hid-1.5.0/hostid-by-egid-modload'
fi
if test -f 'hid-1.5.0/hostid-by-egid-modload/README' && test X"$1" != X"-c"; then
  echo 'x - skipping hid-1.5.0/hostid-by-egid-modload/README (file already exists)'
  rm -f _sharnew.tmp
else
  > _sharnew.tmp
  echo 'x - extracting hid-1.5.0/hostid-by-egid-modload/README (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'hid-1.5.0/hostid-by-egid-modload/README' &&
This is based, in part, upon an anonymous contribution. I've improved
it by making it loadable, so one does not have to build a new kernel.
You'll find the original contribution in ../hostid-by-egid
X
This will probably only work on versions of Sun OS later than 4.1.1.
Certainly there is no support for Solaris 5.x
X
to use this:
make load
make sethostid
X./sethostid 0 72000000
X
which should modify the hostid for processes with gid 900.
X
You can remove the sethostid call by using modunload. You can check
whether or not it is currently installed with modstat.
X
X     This package check running process's effective gid and user's gid
to determine which hostid should be returned.  If the gid is between
900 to 909, the specified hostid will be returned.  Otherwise, the original
hostid will be returned.  Therefore, you can setgid the target checking
excutable file and it will get what you want when the gethostid system
call is called.  For example, we run '/bin/sethostid 0 12345678'.  All
running processes with gid 900 will get hostid as 12345678 rather than
the real hostid.  Remember the hostid above are all hexadecimal values.
X
N.B. sethostid.exec must be executable. Depending upon where you got
the distribution you might have to chmod +x it.
X
see ../run for a small utility for use with this.
SHAR_EOF
  $shar_touch -am 0819114994 'hid-1.5.0/hostid-by-egid-modload/README' &&
  chmod 0600 'hid-1.5.0/hostid-by-egid-modload/README' ||
  echo 'restore of hid-1.5.0/hostid-by-egid-modload/README failed'
  shar_count="`wc -c < 'hid-1.5.0/hostid-by-egid-modload/README'`"
  test 1304 -eq "$shar_count" ||
    echo "hid-1.5.0/hostid-by-egid-modload/README: original size 1304, current size $shar_count"
  rm -f _sharnew.tmp
fi
# ============= hid-1.5.0/hostid-by-egid-modload/kern_hostid.c ==============
if test -f 'hid-1.5.0/hostid-by-egid-modload/kern_hostid.c' && test X"$1" != X"-c"; then
  echo 'x - skipping hid-1.5.0/hostid-by-egid-modload/kern_hostid.c (file already exists)'
  rm -f _sharnew.tmp
else
  > _sharnew.tmp
  echo 'x - extracting hid-1.5.0/hostid-by-egid-modload/kern_hostid.c (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'hid-1.5.0/hostid-by-egid-modload/kern_hostid.c' &&
/*
This program is distributed in the hope that it will be useful,
but without any warranty; without even the implied warranty of
merchantability or fitness for a particular purpose. You use
this program at your own risk. The author disclaims responsibility for
any damages that might result from the use of this program, even
if they result from negligence on the part of the author.
X
Also, please don't use this program to steal software. The intended
use is for emergency situations where an application has to be moved from
one computer to another (e.g. in the event of a hardware malfunction)
and licence keys cannot be obtained quickly from the vendor. Many
vendors will not supply licence keys outside of business hours.
*/
X
#include <sys/param.h>
#include <sys/syscall.h>
#include <sys/systm.h>
#include <sys/user.h>
#include <sun/vddrv.h>
X
#define NHOSTID 10
X
static unsigned hostid[NHOSTID]={0};
X
int sethostid();
X
static struct sysent sethostid_sysent = { 2, sethostid } ;
X
static struct vdlsys vd = {
X  VDMAGIC_SYS, /* magic number */
X  "sethostid", /* name */
X  0, /* syscall number (filled in automagically) */
X  &sethostid_sysent /* description of syscall */
};
X
X
Gethostid()
{
X    unsigned machineid;
X    u_short gid;
X    int i;
X
X    gethostid();
X    machineid = u.u_r.r_val1;
X
X    gid = u.u_gid;
X    if (gid >= 900 && gid < 900+NHOSTID) {
X        u.u_r.r_val1 = hostid[gid-900] ? hostid[gid-900] : machineid;
X        return;
X    }
X
X    i = 0;
X    while (gid=u.u_groups[i++]) {
X        if (gid >= 900 && gid < 900+NHOSTID) {
X            u.u_r.r_val1 = hostid[gid-900] ? hostid[gid-900] : machineid;
X            return;
X        }
X    }
X    u.u_r.r_val1 = machineid;
X    return;
}
X
sethostid(uap)
X    register struct a {
X        int n;
X        unsigned hostid;
X    } *uap;
{
X    if (!suser()) {
X        u.u_error = EACCES;
X        return;
X    }
X
X    if ((uap->n >= NHOSTID )||(uap->n < 0)) {  
X        u.u_error = EINVAL;
X        return;
X    }
X
X    u.u_r.r_val1 = hostid[uap->n] = uap->hostid;
X    u.u_error = 0;
X    return;
}
X
X
sethostidinit(function_code, vdp, vdi, vds)
unsigned int function_code;
struct vddrv *vdp;
addr_t vdi;
struct vdstat *vds;
{
X  switch (function_code) {
X  case VDLOAD:
X    vdp->vdd_vdtab = (struct vdlinkage *)&vd;
X    sysent[SYS_gethostid].sy_narg = 2;
X    sysent[SYS_gethostid].sy_call = Gethostid;
X    return 0;
X  case VDUNLOAD:
X    sysent[SYS_gethostid].sy_narg = 2;
X    sysent[SYS_gethostid].sy_call = gethostid;
X    return 0;
X  case VDSTAT:
X    return 0;
X  default:
X    return EIO;
X  }
}
X
SHAR_EOF
  $shar_touch -am 0811082994 'hid-1.5.0/hostid-by-egid-modload/kern_hostid.c' &&
  chmod 0600 'hid-1.5.0/hostid-by-egid-modload/kern_hostid.c' ||
  echo 'restore of hid-1.5.0/hostid-by-egid-modload/kern_hostid.c failed'
  shar_count="`wc -c < 'hid-1.5.0/hostid-by-egid-modload/kern_hostid.c'`"
  test 2536 -eq "$shar_count" ||
    echo "hid-1.5.0/hostid-by-egid-modload/kern_hostid.c: original size 2536, current size $shar_count"
  rm -f _sharnew.tmp
fi
# ============= hid-1.5.0/hostid-by-egid-modload/makefile ==============
if test -f 'hid-1.5.0/hostid-by-egid-modload/makefile' && test X"$1" != X"-c"; then
  echo 'x - skipping hid-1.5.0/hostid-by-egid-modload/makefile (file already exists)'
  rm -f _sharnew.tmp
else
  > _sharnew.tmp
  echo 'x - extracting hid-1.5.0/hostid-by-egid-modload/makefile (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'hid-1.5.0/hostid-by-egid-modload/makefile' &&
CFLAGS = -DKERNEL
ASFLAGS = -P
X
load: kern_hostid.o
X	chmod +x sethostid.exec
X	/usr/etc/modload kern_hostid.o -v -entry _sethostidinit -exec sethostid.exec
X
sethostid: sethostid.o sethostid.h
X	cc -o sethostid -I. sethostid.c
X
clean:
X	rm -f core *.o sethostid kern_hostid sethostid.h
SHAR_EOF
  $shar_touch -am 0816104194 'hid-1.5.0/hostid-by-egid-modload/makefile' &&
  chmod 0600 'hid-1.5.0/hostid-by-egid-modload/makefile' ||
  echo 'restore of hid-1.5.0/hostid-by-egid-modload/makefile failed'
  shar_count="`wc -c < 'hid-1.5.0/hostid-by-egid-modload/makefile'`"
  test 282 -eq "$shar_count" ||
    echo "hid-1.5.0/hostid-by-egid-modload/makefile: original size 282, current size $shar_count"
  rm -f _sharnew.tmp
fi
# ============= hid-1.5.0/hostid-by-egid-modload/sethostid.c ==============
if test -f 'hid-1.5.0/hostid-by-egid-modload/sethostid.c' && test X"$1" != X"-c"; then
  echo 'x - skipping hid-1.5.0/hostid-by-egid-modload/sethostid.c (file already exists)'
  rm -f _sharnew.tmp
else
  > _sharnew.tmp
  echo 'x - extracting hid-1.5.0/hostid-by-egid-modload/sethostid.c (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'hid-1.5.0/hostid-by-egid-modload/sethostid.c' &&
/*
This program is distributed in the hope that it will be useful,
but without any warranty; without even the implied warranty of
merchantability or fitness for a particular purpose. You use
this program at your own risk. The author disclaims responsibility for
any damages that might result from the use of this program, even
if they result from negligence on the part of the author.
X
Also, please don't use this program to steal software. The intended
use is for emergency situations where an application has to be moved from
one computer to another (e.g. in the event of a hardware malfunction)
and licence keys cannot be obtained quickly from the vendor. Many
vendors will not supply licence keys outside of business hours.
*/
X
#include <stdio.h>
#include <sys/syscall.h>
#include <errno.h>
#include "sethostid.h"
X
main(argc, argv)
int argc;
char *argv[];
{
X  unsigned hostid;
X  int n;
X
X  if (argc<3) {
X    fprintf(stderr, "%s <n> <hostid>\n", argv[0]);
X    exit(1);
X  }
X  n=atoi(argv[1]);
X  sscanf(argv[2], "%x", &hostid);
X  fprintf(stderr, "will set hostid for group %d set to %08x\n", 900+n,hostid);
X  if (syscall(SYS_sethostid, n, hostid)==-1) {
X    perror(argv[0]);
X    exit(1);
X  }
}  
X
SHAR_EOF
  $shar_touch -am 0816104594 'hid-1.5.0/hostid-by-egid-modload/sethostid.c' &&
  chmod 0600 'hid-1.5.0/hostid-by-egid-modload/sethostid.c' ||
  echo 'restore of hid-1.5.0/hostid-by-egid-modload/sethostid.c failed'
  shar_count="`wc -c < 'hid-1.5.0/hostid-by-egid-modload/sethostid.c'`"
  test 1197 -eq "$shar_count" ||
    echo "hid-1.5.0/hostid-by-egid-modload/sethostid.c: original size 1197, current size $shar_count"
  rm -f _sharnew.tmp
fi
# ============= hid-1.5.0/hostid-by-egid-modload/sethostid.exec ==============
if test -f 'hid-1.5.0/hostid-by-egid-modload/sethostid.exec' && test X"$1" != X"-c"; then
  echo 'x - skipping hid-1.5.0/hostid-by-egid-modload/sethostid.exec (file already exists)'
  rm -f _sharnew.tmp
else
  > _sharnew.tmp
  echo 'x - extracting hid-1.5.0/hostid-by-egid-modload/sethostid.exec (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'hid-1.5.0/hostid-by-egid-modload/sethostid.exec' &&
#!/bin/csh -f
echo "#define SYS_sethostid $3" > sethostid.h
SHAR_EOF
  $shar_touch -am 0811082994 'hid-1.5.0/hostid-by-egid-modload/sethostid.exec' &&
  chmod 0700 'hid-1.5.0/hostid-by-egid-modload/sethostid.exec' ||
  echo 'restore of hid-1.5.0/hostid-by-egid-modload/sethostid.exec failed'
  shar_count="`wc -c < 'hid-1.5.0/hostid-by-egid-modload/sethostid.exec'`"
  test 60 -eq "$shar_count" ||
    echo "hid-1.5.0/hostid-by-egid-modload/sethostid.exec: original size 60, current size $shar_count"
  rm -f _sharnew.tmp
fi
# ============= hid-1.5.0/hostid-by-egid-solaris2/README ==============
if test ! -d 'hid-1.5.0/hostid-by-egid-solaris2'; then
  echo 'x - creating directory hid-1.5.0/hostid-by-egid-solaris2'
  mkdir 'hid-1.5.0/hostid-by-egid-solaris2'
fi
if test -f 'hid-1.5.0/hostid-by-egid-solaris2/README' && test X"$1" != X"-c"; then
  echo 'x - skipping hid-1.5.0/hostid-by-egid-solaris2/README (file already exists)'
  rm -f _sharnew.tmp
else
  > _sharnew.tmp
  echo 'x - extracting hid-1.5.0/hostid-by-egid-solaris2/README (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'hid-1.5.0/hostid-by-egid-solaris2/README' &&
This appears to work correctly under Solaris 2.3 and 2.4.
X
Instructions:
X
You need to do everything below as root.
X
1. Add an entry to /etc/name_to_sysnum for the sethostid system call.
For instance, I use the following line.
sethostid       177
X
Do not put any leading whitespace on the line in /etc/name_to_sysnum.
X
The important thing is to pick an unused syscall number. There
is also a limit on the number you can pick, which is determined
by the size of the sysent table. To find out what the limit is
you can use adb (only for 2.3, just be reasonable for Solaris 2.4)
X
adb -k /dev/ksyms /dev/mem
sysentsize/D
^D        #  i.e. control-D
X
You should be able to pick any unused syscall number between 1 and the
number output by adb above minus 1. Alternatively just use an unused
number which is less than the largest number which occurs in
/etc/name_to_sysnum
X
After modifying /etc/name_to_sysnum you must reboot for the change
to take effect.
X
2. Look at the makefile and check that the location of the C compiler is
right for your system. You do NOT want to get /usr/ucb/cc. gcc should
be OK.
X
3. Type
make load
X
This should load the sethostid call. 
X
4. Type 
make sid
X
This makes the program that allows you to modify the hostid for
a particular group.
X
e.g. Now you can modify the hostid for group 900 to be 23000000 by typing
X./sid 0 23000000
X
6. You can unload the system call as follows.
X
Type
/usr/sbin/modinfo
X
X You'll get output which includes a line which looks something like
76 fc42d000   621 177   1  sethostid (kern_hostid v1.0)
X
To remove the module type
/usr/sbin/modunload -i 76
Replace 76 by the first number in the line output by modinfo.
X
7. If you like you can install sid and sethostid by typing
make install
X
If you do this, when you reboot, the sethostid module will be
automatically loaded when sethostid is called (i.e. when you run sid).
X
see ../run for a small utility for use with this.
SHAR_EOF
  $shar_touch -am 0627211195 'hid-1.5.0/hostid-by-egid-solaris2/README' &&
  chmod 0600 'hid-1.5.0/hostid-by-egid-solaris2/README' ||
  echo 'restore of hid-1.5.0/hostid-by-egid-solaris2/README failed'
  shar_count="`wc -c < 'hid-1.5.0/hostid-by-egid-solaris2/README'`"
  test 1924 -eq "$shar_count" ||
    echo "hid-1.5.0/hostid-by-egid-solaris2/README: original size 1924, current size $shar_count"
  rm -f _sharnew.tmp
fi
# ============= hid-1.5.0/hostid-by-egid-solaris2/makefile ==============
if test -f 'hid-1.5.0/hostid-by-egid-solaris2/makefile' && test X"$1" != X"-c"; then
  echo 'x - skipping hid-1.5.0/hostid-by-egid-solaris2/makefile (file already exists)'
  rm -f _sharnew.tmp
else
  > _sharnew.tmp
  echo 'x - extracting hid-1.5.0/hostid-by-egid-solaris2/makefile (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'hid-1.5.0/hostid-by-egid-solaris2/makefile' &&
CFLAGS = -D_KERNEL 
ASFLAGS = -P
CC = /opt/SUNWspro/bin/cc
X
load: sethostid
X	/usr/sbin/modload ./sethostid
X
sethostid: sethostid.o
X	/usr/ccs/bin/ld -r -o sethostid sethostid.o
X
sid: sid.c
X	grep sethostid /etc/name_to_sysnum | sed 's/^/#define SYS_/' >sethostid.h
X	$(CC) -o sid -I. sid.c
X
install: sethostid sid
X	/usr/sbin/install -f /kernel/sys -m 0755 -u root -g sys ./sethostid
X	/usr/sbin/install -f /usr/local/bin -m 0755 -u root -g sys ./sid
X
clean:
X	rm -f core *.o sid sethostid sethostid.h
SHAR_EOF
  $shar_touch -am 0113152795 'hid-1.5.0/hostid-by-egid-solaris2/makefile' &&
  chmod 0600 'hid-1.5.0/hostid-by-egid-solaris2/makefile' ||
  echo 'restore of hid-1.5.0/hostid-by-egid-solaris2/makefile failed'
  shar_count="`wc -c < 'hid-1.5.0/hostid-by-egid-solaris2/makefile'`"
  test 496 -eq "$shar_count" ||
    echo "hid-1.5.0/hostid-by-egid-solaris2/makefile: original size 496, current size $shar_count"
  rm -f _sharnew.tmp
fi
# ============= hid-1.5.0/hostid-by-egid-solaris2/sethostid.c ==============
if test -f 'hid-1.5.0/hostid-by-egid-solaris2/sethostid.c' && test X"$1" != X"-c"; then
  echo 'x - skipping hid-1.5.0/hostid-by-egid-solaris2/sethostid.c (file already exists)'
  rm -f _sharnew.tmp
else
  > _sharnew.tmp
  echo 'x - extracting hid-1.5.0/hostid-by-egid-solaris2/sethostid.c (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'hid-1.5.0/hostid-by-egid-solaris2/sethostid.c' &&
/*
This program is distributed in the hope that it will be useful,
but without any warranty; without even the implied warranty of
merchantability or fitness for a particular purpose. You use
this program at your own risk. The author disclaims responsibility for
any damages that might result from the use of this program, even
if they result from negligence on the part of the author.
X
Also, please don't use this program to steal software. The intended
use is for emergency situations where an application has to be moved from
one computer to another (e.g. in the event of a hardware malfunction)
and licence keys cannot be obtained quickly from the vendor. Many
vendors will not supply licence keys outside of business hours.
X
before you install this modify /etc/name_to_sysnum to bind sethostid to 
an _unused_ system call number
X
As far as I can determine the details of how to load system calls in
Solaris 2.3 are undocumented. I've done this by poking around in the
header files in sys and the man pages, and extrapolating from what 
I know about how loadable device drivers work and how the procedure 
works in Solaris 1.1
X
Mark Henderson <markh@wimsey.bc.ca>
14 Aug 1994
*/
X
#include <sys/param.h>
#include <sys/syscall.h>
#include <sys/systm.h>
#include <sys/user.h>
#include <sys/modctl.h>
#include <sys/cred.h>
#include <sys/systeminfo.h>
X
#define NHOSTID 10
X
static char serials[NHOSTID][16];
char xyzzy_rbuf[16];
X
int sethostid();
X
struct sysent sethostid_sysent = {2,0,sethostid,0};
X
extern struct mod_ops mod_syscallops;
X
static struct modlsys modlsys = {
&mod_syscallops,
"kern_hostid v1.02", 
&sethostid_sysent,
};
X
extern systeminfo();
X
static struct modlinkage modlinkage = {
X    MODREV_1, /* magic number */
X    &modlsys, 
X    0
};
X
struct as2 {int command; char *buf; long count;};
int new_systeminfo(struct as2 *uap, rval_t *foo)
{
X    int ret,i,bsize;
X    gid_t gid;
X    cred_t *creds = CRED();
X    systeminfo(uap,foo);
X    ret = foo->r_val1;
X    if (uap->command == SI_HW_SERIAL) {
X        gid = creds->cr_gid;
X        bsize = (uap->count > 16) ? 16 : uap->count; /* min(16,count)*/
X        if (gid >= 900 && gid < 900+NHOSTID) {
X            if (serials[gid - 900][0]) {
X                for (i=0;i < bsize - 1;i++)
X                    xyzzy_rbuf[i]  = serials[gid-900][i];
X                xyzzy_rbuf[bsize - 1] = 0;
X                ret = strlen(xyzzy_rbuf) + 1;
X                if (copyout(xyzzy_rbuf,uap->buf,ret) < 0)
X                    return EFAULT;
X            }
X        }
X        for (gid = 900; gid < 900+NHOSTID; gid++) {
X            if (groupmember(gid, creds)) {
X                if (serials[gid - 900][0]) {
X                    for (i=0;i< bsize - 1;i++)
X                        xyzzy_rbuf[i]  = serials[gid-900][i];
X                    xyzzy_rbuf[bsize - 1] = 0;
X                    ret = strlen(xyzzy_rbuf) + 1;
X                    if (copyout(xyzzy_rbuf,uap->buf,ret) < 0)
X                        return EFAULT;
X                    break;
X                }
X            }
X        }
X    }
X    foo->r_val1 = ret;
X    return 0;
}
X
struct as {int n; unsigned int hostid;};
X
sethostid(struct as *uap, rval_t *foo)
{
X    cred_t *creds = CRED();
X    if (!suser(creds)) {
X        return EACCES;
X    }
X
X    if ((uap->n >= NHOSTID )||(uap->n < 0)) {  
X        return EINVAL;
X    }
X    numtos( (unsigned long)uap->hostid, &serials[uap->n][0]);
X    foo->r_val1 = uap->hostid;
X    return 0;
}
X
_init(void)
{
X    int i,status;
X    status = mod_install(&modlinkage);
X    if (!status) {
X        sysent[SYS_systeminfo].sy_narg = 3;
X        sysent[SYS_systeminfo].sy_call = new_systeminfo;
X        for (i=0; i < NHOSTID; i++) 
X            serials[i][0] = 0;
X    }
X    return status;
}
_fini(void)
{
X    int status;
X    status = mod_remove(&modlinkage);
X    if (!status) {
X        sysent[SYS_systeminfo].sy_narg = 3;
X        sysent[SYS_systeminfo].sy_call = systeminfo;
X    }
X    return status;
}
X
_info(struct modinfo *modinfop)
{
X    return (mod_info(&modlinkage, modinfop));
}
SHAR_EOF
  $shar_touch -am 0819112494 'hid-1.5.0/hostid-by-egid-solaris2/sethostid.c' &&
  chmod 0600 'hid-1.5.0/hostid-by-egid-solaris2/sethostid.c' ||
  echo 'restore of hid-1.5.0/hostid-by-egid-solaris2/sethostid.c failed'
  shar_count="`wc -c < 'hid-1.5.0/hostid-by-egid-solaris2/sethostid.c'`"
  test 3998 -eq "$shar_count" ||
    echo "hid-1.5.0/hostid-by-egid-solaris2/sethostid.c: original size 3998, current size $shar_count"
  rm -f _sharnew.tmp
fi
# ============= hid-1.5.0/hostid-by-egid-solaris2/sid.c ==============
if test -f 'hid-1.5.0/hostid-by-egid-solaris2/sid.c' && test X"$1" != X"-c"; then
  echo 'x - skipping hid-1.5.0/hostid-by-egid-solaris2/sid.c (file already exists)'
  rm -f _sharnew.tmp
else
  > _sharnew.tmp
  echo 'x - extracting hid-1.5.0/hostid-by-egid-solaris2/sid.c (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'hid-1.5.0/hostid-by-egid-solaris2/sid.c' &&
/*
This program is distributed in the hope that it will be useful,
but without any warranty; without even the implied warranty of
merchantability or fitness for a particular purpose. You use
this program at your own risk. The author disclaims responsibility for
any damages that might result from the use of this program, even
if they result from negligence on the part of the author.
X
Also, please don't use this program to steal software. The intended
use is for emergency situations where an application has to be moved from
one computer to another (e.g. in the event of a hardware malfunction)
and licence keys cannot be obtained quickly from the vendor. Many
vendors will not supply licence keys outside of business hours.
*/
X
#include <stdio.h>
#include <sys/syscall.h>
#include <errno.h>
#include "sethostid.h"
X
main(argc, argv)
int argc;
char *argv[];
{
X  unsigned hostid;
X  int n;
X
X  if (argc<3) {
X    fprintf(stderr, "%s <n> <hostid>\n", argv[0]);
X    exit(1);
X  }
X  n=atoi(argv[1]);
X  hostid=strtoul(argv[2], NULL, 16);
X  if (syscall(SYS_sethostid, n, hostid)==-1) {
X    perror(argv[0]);
X    exit(1);
X  }
}  
X
SHAR_EOF
  $shar_touch -am 0819112594 'hid-1.5.0/hostid-by-egid-solaris2/sid.c' &&
  chmod 0600 'hid-1.5.0/hostid-by-egid-solaris2/sid.c' ||
  echo 'restore of hid-1.5.0/hostid-by-egid-solaris2/sid.c failed'
  shar_count="`wc -c < 'hid-1.5.0/hostid-by-egid-solaris2/sid.c'`"
  test 1121 -eq "$shar_count" ||
    echo "hid-1.5.0/hostid-by-egid-solaris2/sid.c: original size 1121, current size $shar_count"
  rm -f _sharnew.tmp
fi
# ============= hid-1.5.0/hostid-by-egid/README ==============
if test ! -d 'hid-1.5.0/hostid-by-egid'; then
  echo 'x - creating directory hid-1.5.0/hostid-by-egid'
  mkdir 'hid-1.5.0/hostid-by-egid'
fi
if test -f 'hid-1.5.0/hostid-by-egid/README' && test X"$1" != X"-c"; then
  echo 'x - skipping hid-1.5.0/hostid-by-egid/README (file already exists)'
  rm -f _sharnew.tmp
else
  > _sharnew.tmp
  echo 'x - extracting hid-1.5.0/hostid-by-egid/README (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'hid-1.5.0/hostid-by-egid/README' &&
Contributed by someone who wishes to remain anonymous. 
X
I've made a couple of minor modifications. - markh@wimsey.bc.ca
X
This program is distributed in the hope that it will be useful,
but without any warranty; without even the implied warranty of
merchantability or fitness for a particular purpose. You use
this program at your own risk. The author disclaims responsibility for
any damages that might result from the use of this program, even
if they result from negligence on the part of the author.
X
Also, please don't use this program to steal software. The intended
use is for emergency situations where an application has to be moved from
one computer to another (e.g. in the event of a hardware malfunction)
and licence keys cannot be obtained quickly from the vendor. Many
vendors will not supply licence keys outside of business hours.
X
--
X
X     Most commericial packages are bounded to machine hostid for protection.
This ID is built in PROM on Sun Sparc machine.  The purpose of this program
is to let you specify the hostid freely and you can run the commericial
programs on another machine with differnet machine hostid.  This package is
tested and works fine on SunOS 4.1.2, 4.1.3 and 4.1.3_U1.
X
INSTALLATION:
X
step 1.
X  Copy kern_hostid.c into /sys/os
X
step 2.
X  Add the following line in /sys/conf.common/files.cmn
X	os/kern_hostid.c	standard
X
step 3.
X  Replace gethostid declartion with Gethostid, and add the new declartion
of sethostid.  Change system call 143 into sethostid.  The modified version
of /sys/os/init_sysent.c should contain the following lines.
X
line 25:
int     Gethostid(),sethostname(),gethostname(),getpid();
line 32:
int	sethostid();
line 362:
X        2, Gethostid,                   /* 142 = gethostid */
X        2, sethostid,                   /* 143 = old sethostid */
X
step 4:
X  Configure your own kernel and rebuild it.  Install it in /vmunix and
reboot.
X
step 5:
X  Compile sethostid.c and install sethostid in /bin.
X
step 6:
X  Done.
X
USAGE:
X     This package check running process's effective gid and user's gid
to determine which hostid should be returned.  If the gid is between
900 to 909, the specified hostid will be returned.  Otherwise, the original
hostid will be returned.  Therefore, you can setgid the target checking
excutable file and it will get what you want when the gethostid system
call is called.  For example, we run '/bin/sethostid 0 12345678'.  All
running processes with gid 900 will get hostid as 12345678 rather than
the real hostid.  Remember the hostid above are all heximal value.
X     If you have any problem, try to see the source code.  No help is
provided.
X
see ../run for a small utility for use with this.
SHAR_EOF
  $shar_touch -am 0819114994 'hid-1.5.0/hostid-by-egid/README' &&
  chmod 0600 'hid-1.5.0/hostid-by-egid/README' ||
  echo 'restore of hid-1.5.0/hostid-by-egid/README failed'
  shar_count="`wc -c < 'hid-1.5.0/hostid-by-egid/README'`"
  test 2686 -eq "$shar_count" ||
    echo "hid-1.5.0/hostid-by-egid/README: original size 2686, current size $shar_count"
  rm -f _sharnew.tmp
fi
# ============= hid-1.5.0/hostid-by-egid/kern_hostid.c ==============
if test -f 'hid-1.5.0/hostid-by-egid/kern_hostid.c' && test X"$1" != X"-c"; then
  echo 'x - skipping hid-1.5.0/hostid-by-egid/kern_hostid.c (file already exists)'
  rm -f _sharnew.tmp
else
  > _sharnew.tmp
  echo 'x - extracting hid-1.5.0/hostid-by-egid/kern_hostid.c (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'hid-1.5.0/hostid-by-egid/kern_hostid.c' &&
/*
This program is distributed in the hope that it will be useful,
but without any warranty; without even the implied warranty of
merchantability or fitness for a particular purpose. You use
this program at your own risk. The author disclaims responsibility for
any damages that might result from the use of this program, even
if they result from negligence on the part of the author.
X
Also, please don't use this program to steal software. The intended
use is for emergency situations where an application has to be moved from
one computer to another (e.g. in the event of a hardware malfunction)
and licence keys cannot be obtained quickly from the vendor. Many
vendors will not supply licence keys outside of business hours.
*/
X
#include <sys/user.h>
#define NHOSTID 10
X
static unsigned hostid[NHOSTID]={0};
X
Gethostid()
{
X    unsigned machineid;
X    u_short gid;
X    int i;
X
X    gethostid();
X    machineid = u.u_r.r_val1;
X
X    gid = u.u_gid;
X    if (gid >= 900 && gid < 900+NHOSTID) {
X        u.u_r.r_val1 = hostid[gid-900] ? hostid[gid-900] : machineid;
X        return;
X    }
X
X    i = 0;
X    while (gid=u.u_groups[i++]) {
X        if (gid >= 900 && gid < 900+NHOSTID) {
X            u.u_r.r_val1 = hostid[gid-900] ? hostid[gid-900] : machineid;
X            return;
X        }
X    }
X    u.u_r.r_val1 = machineid;
X    return;
}
X
sethostid(uap)
X    register struct a {
X        int n;
X        unsigned hostid;
X    } *uap;
{
X    if (!suser()) {
X        u.u_error = EACCES;
X        return;
X    }
X
X    if ((uap->n >= NHOSTID )||(uap->n < 0)) {  /* small change - markh */
X        u.u_error = EINVAL;
X        return;
X    }
X
X    u.u_r.r_val1 = hostid[uap->n] = uap->hostid;
X    u.u_error = 0;
X    return;
}
SHAR_EOF
  $shar_touch -am 0816104894 'hid-1.5.0/hostid-by-egid/kern_hostid.c' &&
  chmod 0600 'hid-1.5.0/hostid-by-egid/kern_hostid.c' ||
  echo 'restore of hid-1.5.0/hostid-by-egid/kern_hostid.c failed'
  shar_count="`wc -c < 'hid-1.5.0/hostid-by-egid/kern_hostid.c'`"
  test 1700 -eq "$shar_count" ||
    echo "hid-1.5.0/hostid-by-egid/kern_hostid.c: original size 1700, current size $shar_count"
  rm -f _sharnew.tmp
fi
# ============= hid-1.5.0/hostid-by-egid/sethostid.c ==============
if test -f 'hid-1.5.0/hostid-by-egid/sethostid.c' && test X"$1" != X"-c"; then
  echo 'x - skipping hid-1.5.0/hostid-by-egid/sethostid.c (file already exists)'
  rm -f _sharnew.tmp
else
  > _sharnew.tmp
  echo 'x - extracting hid-1.5.0/hostid-by-egid/sethostid.c (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'hid-1.5.0/hostid-by-egid/sethostid.c' &&
/*
This program is distributed in the hope that it will be useful,
but without any warranty; without even the implied warranty of
merchantability or fitness for a particular purpose. You use
this program at your own risk. The author disclaims responsibility for
any damages that might result from the use of this program, even
if they result from negligence on the part of the author.
X
Also, please don't use this program to steal software. The intended
use is for emergency situations where an application has to be moved from
one computer to another (e.g. in the event of a hardware malfunction)
and licence keys cannot be obtained quickly from the vendor. Many
vendors will not supply licence keys outside of business hours.
*/
X
#include <stdio.h>
#include <sys/syscall.h>
#include <errno.h>
X
main(argc, argv)
int argc;
char *argv[];
{
X  unsigned hostid;
X  int n;
X
X  if (argc<3) {
X    fprintf(stderr, "%s <n> <hostid>\n", argv[0]);
X    exit(1);
X  }
X  n=atoi(argv[1]);
X  sscanf(argv[2], "%x", &hostid);
X  if (syscall(143, n, hostid)==-1) {
X    perror(argv[0]);
X    exit(1);
X  }
}  
X
SHAR_EOF
  $shar_touch -am 0816104894 'hid-1.5.0/hostid-by-egid/sethostid.c' &&
  chmod 0600 'hid-1.5.0/hostid-by-egid/sethostid.c' ||
  echo 'restore of hid-1.5.0/hostid-by-egid/sethostid.c failed'
  shar_count="`wc -c < 'hid-1.5.0/hostid-by-egid/sethostid.c'`"
  test 1085 -eq "$shar_count" ||
    echo "hid-1.5.0/hostid-by-egid/sethostid.c: original size 1085, current size $shar_count"
  rm -f _sharnew.tmp
fi
# ============= hid-1.5.0/newhostid ==============
if test -f 'hid-1.5.0/newhostid' && test X"$1" != X"-c"; then
  echo 'x - skipping hid-1.5.0/newhostid (file already exists)'
  rm -f _sharnew.tmp
else
  > _sharnew.tmp
  echo 'x - extracting hid-1.5.0/newhostid (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'hid-1.5.0/newhostid' &&
#!/bin/sh
#newhostid
#Author: Jean-Louis Faraut [jlf]
#Organization: Ecole Superieure en Sciences Informatiques 
#   (Universite de Nice Sophia-Antipolis)
#Address: Sophia-Antipolis (France)
#
# This program is distributed in the hope that it will be useful,
# but without any warranty; without even the implied warranty of
# merchantability or fitness for a particular purpose. You use
# this program at your own risk. The author disclaims responsibility for
# any damages that might result from the use of this program, even
# if they result from negligence on the part of the author.
# 
# Also, please don't use this program to steal software. The intended
# use is for emergency situations where an application has to be moved from
# one computer to another (e.g. in the event of a hardware malfunction)
# and licence keys cannot be obtained quickly from the vendor. Many
# vendors will not supply licence keys outside of business hours.
#
#run a Sun dynamically linked executable  with a new hostid
# - notes - only works on a Sun. Only tested under Solaris 2.3 and 1.[01]
#         - only works with dymanically linked executables.
#
# SunOS 5.x code is an alpha release (not fully tested)
# usage:
#   newhostid Base10Hostid command [args]
# On Solaris 1.x (Sun OS 4.1.x) you can also
#  newhostid 0x72000000 command
#   if you want to use hex
# Sun OS 5.x note:
# if it turns out that you need somewhat more complete sysinfo emulation
#  check out sidump.c
#Warning: The following file names are used by this script:
#/tmp/gethostid.{c,o,so}           -> if OS == SunOS 4.1.x
#/tmp/sysinfo.{c,c.head,c.tail,so} -> if OS == SunOS 5.x
#
#modify the following line to meet your site requirement
GCC=/opt/gnu/bin/gcc	#only required by SunOS 5.x
#
if [ $# -lt 2 ] 
then
X	echo 'Usage:newhostid hostid(base 10) command [args]'
X	exit 1
fi
X
case `/usr/bin/uname -s` in
X     SunOS) ;;
X     *) echo 'Only for SunOS. Sorry.'
X     exit 1 ;;
esac
X
case `/usr/bin/uname -r` in
X     4.1.*)
X     (cd /tmp
X     cat > gethostid.c <<!
X     gethostid()
X     {
X       return $1;
X       }
!
X       cc -c gethostid.c
X       ld gethostid.o -assert pure-text -o gethostid.so
X       rm gethostid.o gethostid.c
X       )
X
X       shift
X       LD_PRELOAD="/tmp/gethostid.so" $*
X       rm /tmp/gethostid.so
X     ;;
X
X     5.*)
X     (cd /tmp
X     # first part of program
X     STRLEN=`expr $1 : '.*'`
X     cat > sysinfo.c.head <<!
X     long sysinfo(command,buf,count)
X     int command; char *buf; long count;
X     {
!
X
X     # second part of program
X     touch sysinfo.c.tail
X     DOT=""
X     COUNT=0
X     while [ $COUNT -lt $STRLEN ]
X     do
X     	echo "  buf[$COUNT] = '`expr $1 : ${DOT}'\(.\)'`';" >> sysinfo.c.tail
X		DOT=${DOT}.
X			COUNT=`expr $COUNT + 1`
X
X			done
X			echo "buf[$COUNT] = 0;"  >> sysinfo.c.tail
X			cat >> sysinfo.c.tail <<!
X			  return 11l;
X			  }
!
X
X			  cat sysinfo.c.head sysinfo.c.tail > sysinfo.c
X			  rm sysinfo.c.head sysinfo.c.tail
X			  #debug: cat sysinfo.c
X			  $GCC -fpic -c sysinfo.c
X			  ld sysinfo.o  -G -o sysinfo.so
X			  rm sysinfo.o sysinfo.c
X			  )
X
X			  shift
X			  LD_PRELOAD=/tmp/sysinfo.so $*
X			  rm /tmp/sysinfo.so
X    ;;
X
esac
X
X
SHAR_EOF
  $shar_touch -am 0811082994 'hid-1.5.0/newhostid' &&
  chmod 0700 'hid-1.5.0/newhostid' ||
  echo 'restore of hid-1.5.0/newhostid failed'
  shar_count="`wc -c < 'hid-1.5.0/newhostid'`"
  test 3145 -eq "$shar_count" ||
    echo "hid-1.5.0/newhostid: original size 3145, current size $shar_count"
  rm -f _sharnew.tmp
fi
# ============= hid-1.5.0/newhostid.old ==============
if test -f 'hid-1.5.0/newhostid.old' && test X"$1" != X"-c"; then
  echo 'x - skipping hid-1.5.0/newhostid.old (file already exists)'
  rm -f _sharnew.tmp
else
  > _sharnew.tmp
  echo 'x - extracting hid-1.5.0/newhostid.old (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'hid-1.5.0/newhostid.old' &&
#!/bin/sh
#newhostid
#Solaris 1.x only
#Author: Jean-Louis Faraut [jlf]
#Organization: Ecole Superieure en Sciences Informatiques (Universite de Nice Sophia-Antipolis)
#Address: Sophia-Antipolis (France)
#run a command with a new hostid
#
# This program is distributed in the hope that it will be useful,
# but without any warranty; without even the implied warranty of
# merchantability or fitness for a particular purpose. You use
# this program at your own risk. The author disclaims responsibility for
# any damages that might result from the use of this program, even
# if they result from negligence on the part of the author.
# 
# Also, please don't use this program to steal software. The intended
# use is for emergency situations where an application has to be moved from
# one computer to another (e.g. in the event of a hardware malfunction)
# and licence keys cannot be obtained quickly from the vendor. Many
# vendors will not supply licence keys outside of business hours.
#
if [ $# -lt 2 ] 
then
X	echo Usage:newhostid hostid command [args]
X	exit 1
fi
(cd /tmp
cat > gethostid.c <<!
gethostid()
{
X  return 0x$1;
}
!
cc -c gethostid.c
ld gethostid.o -assert pure-text -o gethostid.so
rm gethostid.o gethostid.c
)
X
shift
LD_PRELOAD="/tmp/gethostid.so" $*
rm /tmp/gethostid.so
SHAR_EOF
  $shar_touch -am 0811082994 'hid-1.5.0/newhostid.old' &&
  chmod 0700 'hid-1.5.0/newhostid.old' ||
  echo 'restore of hid-1.5.0/newhostid.old failed'
  shar_count="`wc -c < 'hid-1.5.0/newhostid.old'`"
  test 1289 -eq "$shar_count" ||
    echo "hid-1.5.0/newhostid.old: original size 1289, current size $shar_count"
  rm -f _sharnew.tmp
fi
# ============= hid-1.5.0/nvram-sol2.c ==============
if test -f 'hid-1.5.0/nvram-sol2.c' && test X"$1" != X"-c"; then
  echo 'x - skipping hid-1.5.0/nvram-sol2.c (file already exists)'
  rm -f _sharnew.tmp
else
  > _sharnew.tmp
  echo 'x - extracting hid-1.5.0/nvram-sol2.c (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'hid-1.5.0/nvram-sol2.c' &&
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/uio.h>
#include <nlist.h>
#include <sys/systeminfo.h>
#include <sys/openpromio.h>
X
X
/* 
get/change hostid in NVRAM -- Solaris 2.4 only 
X
Instructions:
see the file INSTRUCTIONS. Especially important for sun4d and sun4m
X  class machines.
X
X
UNLESS YOU KNOW EXACTLY WHAT YOU ARE DOING, YOU SHOULD AVOID CHANGING
THE FIRST BYTE OF YOUR HOSTID WHICH IDENTIFIES YOUR SYSTEM TYPE. 
CHANGING THIS BYTE COULD RENDER YOUR SYSTEM UNBOOTABLE.
X
Mark Henderson <markh@wimsey.bc.ca>
Placed in the public domain by the author - Jan 1995
X
This program is distributed in the hope that it will be useful,
but without any warranty; without even the implied warranty of
merchantability or fitness for a particular purpose. You use
this program at your own risk. The author disclaims responsibility for
any damages that might result from the use of this program, even
if they result from negligence on the part of the author.
X
Also, please don't use this program to steal software. The intended
use is for emergency situations where an application has to be moved from
one computer to another (e.g. in the event of a hardware malfunction)
and licence keys cannot be obtained quickly from the vendor. Many
vendors will not supply licence keys outside of business hours.
X
Sorry about all the legal BS, but given that use of this program is
dangerous and inexperienced people will use it, I don't have much choice
from both an ethical and legal point of view.
X
*/
X
X
/* 
X * getobphostid - gets hostid according to the openprom driver
X * returns 0 on failure 
X */
unsigned int getobphostid()
{
X    struct opio {
X       unsigned int size;
X       unsigned char arr[OPROMMAXPARAM];
X    } foo;
X    int fd,done = 0;
X    if ((fd = open("/dev/openprom", O_RDONLY)) < 0) {
X        return (0);
X    }
X    foo.size =  OPROMMAXPARAM;
X    memset(&foo.arr[0],0,OPROMMAXPARAM);
X    if (ioctl(fd, OPROMNEXT, &foo) < 0) {
X        return(0);
X    }
X    foo.size =  OPROMMAXPARAM;
X    memset(&foo.arr[0],0,OPROMMAXPARAM);
X    for (;!done;) {
X        foo.size =  OPROMMAXPARAM;
X        if (ioctl(fd, OPROMNXTPROP, &foo) < 0) {
X            return(0);
X        }
X        if (foo.size == 0)   /* not on list ! */
X            return 0;
X        if (strncmp(&foo.arr[0], "idprom", 6)) 
X            continue;
X        strcpy(&foo.arr[0],&foo.arr[0]);
X        foo.size=OPROMMAXPARAM;
X        if (ioctl(fd, OPROMGETPROP, &foo) < 0) {
X            return(0);
X        }
X        done=1;
X    }   
X    close(fd);
X    return ((foo.arr[1] << 24)|(foo.arr[12] << 16)|(foo.arr[13] << 8)
X            |(foo.arr[14]));
}
X
#define OFFSET1 017730       /* for Sun 4m */
#define OFFSET2 03730     /* for Sun 4c */
X
/* #define TEST        /* doesn't actually do mods if TEST is defined */
unsigned char buf[17];  /* larger than it needs to be */ 
X
/* offset table -- in ascending order of magnitude */
off_t offtab[2] = { OFFSET2, OFFSET1 };
#define nofftab  (sizeof(offtab) / sizeof(off_t))
off_t offset;
struct nlist nl[2];
X
unsigned int bsd_gethostid()
{
X    unsigned char buf[1024];
X    buf[0] = 0;
X    sysinfo(SI_HW_SERIAL, buf, 1024);
X    return (strtoul(buf,NULL,10));
}
void check_eeprom_driver()
{
X    int kmem;
X    off_t where;
X    unsigned int kbuf[12];
X    fprintf(stderr,"nvram-sol2 - Mark Henderson <markh@wimsey.bc.ca>\n");
X    fprintf(stderr,
X        "Placed in the public domain by the author - Jan 1995\n\n");
X    fprintf(stderr,
X        "This program is distributed in the hope that it will be useful,\n");
X    fprintf(stderr,
X        "but without any warranty; without even the implied warranty of\n");
X    fprintf(stderr,
X        "merchantability or fitness for a particular purpose. You use\n");
X    fprintf(stderr,
X    "this program at your own risk. The author disclaims responsibility for\n");
X    fprintf(stderr,
X        "any damages that might result from the use of this program, even\n");
X    fprintf(stderr,
X        "if they result from negligence on the part of the author.\n");
X    fprintf(stderr, 
X        "Malfunction or misuse of this program can damage your computer.\n\n");
X    if ((kmem = open("/dev/kmem", O_RDONLY)) < 0) {
X        fprintf(stderr, "cannot open /dev/kmem\n");
X        exit(1);
X    }
X    nl[0].n_name = "nvram";
X    nl[1].n_name = NULL;
X    if (nlist("/dev/ksyms", nl) < 0) {
X        fprintf(stderr, "cannot read namelist out of /vmunix\n");
X        exit(1);
X    }
X    if ((where = nl[0].n_value) == 0) {
X        fprintf(stderr, "unknown kernel variable nvram\n");
X        fprintf(stderr, "execute the following and try again\n");
X        fprintf(stderr, "/usr/sbin/modload /kernel/drv/eeprom\n");
X        exit(1);
X    }
X    if (lseek(kmem, where, SEEK_SET) == (-1)) {
X        fprintf(stderr, "lseek on /dev/kmem failed\n");
X        fprintf(stderr,
X            "your kernel is strange - nvram modifier won't operate\n");
X        exit(1);
X    }
X    if (read(kmem, (char *)&kbuf[0], 48) < 48) {
X        fprintf(stderr, "read from /dev/kmem failed\n");
X        fprintf(stderr,
X            "your kernel is strange - nvram modifier won't operate\n");
X        exit(1);
X    }
X    close(kmem);
X    if (kbuf[11] == 0x9422a028) {
X        fprintf(stderr, "please execute the following\n");
X        fprintf(stderr,
X            "adb -k -w /dev/ksyms /dev/mem <<END\nnvram+2c/W 9422a000\nEND\n");
X        exit(0);
X    }
X    if (kbuf[11] == 0x9422a000) {
X        fprintf(stderr, "your kernel looks good\n");
X    }
}
X
/* #define gethostid() getobphostid() */
#define gethostid() bsd_gethostid()
X
main(argc,argv)
int argc;
char *argv[];
{
X    unsigned int hid;
X    int fd;
X    int i;
X    int j;
X    unsigned int acc;
X    char obuf[20];
X    int read_hostid;
X    unsigned int hid_reported_by_gethostid = gethostid();
X
X    if (argc == 1) {
X        /* no args - just get hostid from prom */
X        read_hostid = 1;
X    }
X    else if (argc == 2 || argc == 3) {
X        read_hostid = 0;
X        sscanf(argv[1],"%08x",&hid);
X        if (argc == 3)  /* undocumented -- allows you to override the
X                           value returned by sysinfo in the sanity checks */
X            sscanf(argv[2],"%08x",&hid_reported_by_gethostid);
X    }
X    else {
X        fprintf(stderr, "usage: %s [hostid]\n",argv[0]);
X        fprintf(stderr, "  e.g. %s\n", argv[0]);
X        fprintf(stderr, "       %s b0b1fb0b\n", argv[0]);
X        exit(1);
X    }
X
X    check_eeprom_driver();
X    
X    if (read_hostid) {
X        if ((fd = open("/dev/eeprom", O_RDONLY)) < 0) {
X            fprintf(stderr, "cannot open /dev/eeprom for read\n");
X            exit(1);
X        }
X    } 
X    else {
#ifdef TEST
X        if ((fd = open("/dev/eeprom", O_RDONLY)) < 0) {
X            fprintf(stderr, "cannot open /dev/eeprom for read\n");
X            exit(1);
X        }
#else
X        if ((fd = open("/dev/eeprom", O_RDWR)) < 0) {
X            fprintf(stderr, "cannot open /dev/eeprom for write\n");
X            exit(1);
X        }
#endif
X    }
X
X    offset = 0xffffffff;     /* dummy value */
X
X    for (j = 0; j < nofftab; j++) {
X        if (lseek(fd,offtab[j],SEEK_SET) < 0) { 
X            fprintf(stderr, "lseek failed for %o\n", offtab[j]);
X            continue;
X        }
X        if (read(fd,buf,16) < 16) {
X            fprintf(stderr, "read of /dev/eeprom failed for %o\n", offtab[j]);
X            fprintf(stderr, "read of /dev/eeprom failed for %o\n", offtab[j]);
X            continue;
X        }
#ifdef TEST
X        for (i=0; i<16; i++)
X            printf("%02x ", buf[i]);
X        printf("\n");
#endif
X
/*
X The check below will fail if sysinfo does not return the same hostid
X as in NVRAM. This can happen because you've already modified the NVRAM
X and not rebooted since then, or because you've modified the kernel
X so that sysinfo does not return the same hostid as in NVRAM
*/
X
X        for (acc = 0 , i=0; i<15; i++) acc^=buf[i];
X        if ((acc != buf[15]) 
X            || (buf[1] != (hid_reported_by_gethostid >> 24) )
X            || (buf[12] != ((hid_reported_by_gethostid >> 16) &0xff))
X            || (buf[13] != ((hid_reported_by_gethostid >> 8) &0xff))
X            || (buf[14] != (hid_reported_by_gethostid &0xff))) {
X            continue;
X        }
X        offset = offtab[j];
X        break;
X    }
X    if (offset == 0xffffffff) {
X        fprintf(stderr, "perhaps you have a weird kernel -- failed\n");
X        exit(1);
X    }
X    printf("current hostid = %02x%02x%02x%02x\n", 
X    buf[1], buf[12], buf[13], buf[14]);
X
X    /* may as well print this out */
X    printf("enetaddr       = %02x:%02x:%02x:%02x:%02x:%02x\n", 
X    buf[2], buf[3], buf[4], buf[5], buf[6], buf[7]);
X    if (!read_hostid) {
X        if (lseek(fd,offset,SEEK_SET) < 0) { 
X            fprintf(stderr, "lseek failed\n");
X            exit(1);
X        }
X
X        buf[1] = hid >> 24;
X        buf[12] = (hid >> 16) &0xff;
X        buf[13] = (hid >> 8) &0xff;
X        buf[14] = hid &0xff;
X        for (acc = 0 , i=0; i<15; i++) acc^=buf[i];
X        buf[15] = acc & 0xff;
#ifndef TEST
X        if (write(fd,buf,16) < 16) {
X            fprintf(stderr, "write failed\n");
X        }
X        fprintf(stderr,"new hostid is %08x\n", hid);
X		fprintf(stderr, "if you are NOT executing this on an SC1000/2000, skip to (*)\n");
X		fprintf(stderr, "\tpress STOP-A\n");
X		fprintf(stderr, "\ttype \"update-system-idprom\" at the ok prompt\n");
X		fprintf(stderr, "\ttype \"go\" at the ok prompt\n");
X		fprintf(stderr, "\treboot with \"init 6\"\n");
X        fprintf(stderr,"(*) now please execute the following or reboot:\n\n");
X        sprintf(obuf,"%u", hid);  
X        printf("adb -w -k /kernel/unix /dev/mem <<END\n");
X        printf("hw_serial/W 0x");
X        for (i=0; i<4; i++)
X            printf("%02x", obuf[i]);
X        printf("\n");
X        printf("hw_serial+4/W 0x");
X        for (; i<8; i++)
X            printf("%02x", obuf[i]);
X        printf("\n");
X        printf("hw_serial+8/W 0x");
X        for (; i<12; i++)
X            printf("%02x", obuf[i]);
X        printf("\n");
X        printf("END\n");
#else
X    for (i=0; i<16; i++)
X        printf("%02x ", buf[i]);
X    printf("\n");
#endif
X    }
X    close(fd);
}
X
SHAR_EOF
  $shar_touch -am 0908085095 'hid-1.5.0/nvram-sol2.c' &&
  chmod 0600 'hid-1.5.0/nvram-sol2.c' ||
  echo 'restore of hid-1.5.0/nvram-sol2.c failed'
  shar_count="`wc -c < 'hid-1.5.0/nvram-sol2.c'`"
  test 10095 -eq "$shar_count" ||
    echo "hid-1.5.0/nvram-sol2.c: original size 10095, current size $shar_count"
  rm -f _sharnew.tmp
fi
# ============= hid-1.5.0/nvram.c ==============
if test -f 'hid-1.5.0/nvram.c' && test X"$1" != X"-c"; then
  echo 'x - skipping hid-1.5.0/nvram.c (file already exists)'
  rm -f _sharnew.tmp
else
  > _sharnew.tmp
  echo 'x - extracting hid-1.5.0/nvram.c (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'hid-1.5.0/nvram.c' &&
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/uio.h>
#include <nlist.h>
X
X
/* 
get/change hostid in NVRAM -- Solaris 1.1 only
X
Instructions:
X
1. Read this entire comment. Especially the warnings and disclaimers.
X
2. compile nvram
X   cc -o nvram nvram.c
X
3. Run nvram without any parameters.
If it fails with some bizarre error message, then your architecture
is not supported. If you don't mind hacking the kernel you can probably
hack in support for your architecture.  If you send me mods I'll fold
them in to the distribution.  It should suggest a few adb commands
to execute to make a kernel modification.
X
4. Run nvram again without any parameters.  It just prints out the
hostid and hw ethernet address.  Check this against the arp tables on
another machine or against to information displayed on boot. If it is
not correct, do not proceed with the next step.
X
5. now you can try and modify the hostid by running
nvram with the desired hostid as the second parameter (without 0x)
e.g.
nvram b0b1fb0b
X
---
X
Notes:
only tested on sun4m architecture and sun4c architecture. The
kernel patches will be different for Sun4 and I don't have one
to play with. 
X
you can actually do this on a sun3x machine (sun 3/80). Just remove the
stuff that tries to suggest and check for kernel patches
(check_eeprom_driver). The appropriate bytes are accessible directly
via /dev/eeprom. (Sun OS 4.1.1)
X
If your particular machine is not supported, you may be able
to hack support for the machine into this program.
X
This program is still experimental. Dangerous and tricky stuff.
If you are unwilling to experiment and clean up after disasters
don't use it.  USE AT YOUR OWN RISK.  If this program malfunctions
or it is misused, you can get your Sun into a state where it will
not boot, even from CDROM.
X
first you need to turn off the protection in the OS to keep
you from modifying /dev/eeprom locations after 017730 (or the other offset)
X
nvram will try and figure out what your kernel looks like and suggest
a change to execute using adb. 
X
If you don't care about technical details, follow the instructions below.
The commands will be one of the following:
sun4m machines 
adb -k -w /vmunix /dev/mem
_mmeeprom+8/W 901223ff
X
which changes
or      %o1, 0x3d8, %o1
to
or      %o1, 0x3ff, %o1
X
X
OR
(Sun4c)
X
adb -w /vmunix /dev/mem
_mmeeprom+4/W 80a6a7ff
_mmeeprom+0x28/W 80a6a7ff
which changes a couple of compare operations. 
X
Also be very careful choosing a new hostid.  The first byte of the
hostid identifies the type of system you are running. On modern Suns, OS
boot CDs depend on this information to get the correct architecture. If
you change it you may be reduced to poking around in NVRAM from the
monitor next time you have to boot from CD.
X
Here's a mapping of what gets read into buf (at OFFSET)
buf[0] = always 01?
buf[1] = system id/first byte of hostid.
buf[2] \
buf[3]  \
buf[4]   \  HW ethernet address (6 bytes)
buf[5]    /  
buf[6]  /
buf[7]/
buf[8],...,buf[11] = always 00?
buf[12] = second byte of hostid
buf[13] = third byte of hostid
buf[14] = fourth byte of hostid
buf[15] = checksum
X
the checksum is buf[0] ^ buf[1] ^ ... ^ buf[14]
i.e. it must be the case that the  xor of buf[0] through buf[15] is 0
X
X
Mark Henderson <markh@wimsey.bc.ca>
Placed in the public domain by the author - 23 June 1994
X
This program is distributed in the hope that it will be useful,
SHAR_EOF
  : || echo 'restore of hid-1.5.0/nvram.c failed'
fi
echo 'End of archive part 2'
echo 'File hid-1.5.0/nvram.c is continued in part 3'
echo 3 > _sharseq.tmp
exit 0
-- 
Mark Henderson -- markh@wimsey.bc.ca, henderso@netcom.com, mch@squirrel.com
PGP 1024/C58015E3 fingerprint=21 F6 AF 2B 6A 8A 0B E1 A1 2A 2A 06 4A D5 92 46
cryptography archive maintainer  --  ftp://ftp.wimsey.com/pub/crypto
ftp://ftp.netcom.com/pub/he/henderso/change-sun-hostid-1.4.9.tar.gz


