/* 

change hostid reported by Solaris 1.x/SUN OS 4.1.x gethostid
run the script produced by this file 
 
e.g. you could put the following script (produced by hid b0b1fb0b)
   in /etc/rc.local

#!/bin/sh
# this script sets the hostid to b0b1bb0b
adb -w -k /vmunix /dev/mem <<END
_gethostid+4/W 112c2c6e
_gethostid+8/W 9012230b
END

to change the hostid to b0b1fb0b

Mark Henderson <mch@squirrel.com>
Placed in the public domain by the author - 3 June 1994

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.

By way of explanation:

hid produces a script which, when executed on a Solaris 1.x machine
will change the value reported by gethostid to the desired value.  adb
is used to alter the in-core kernel image.  No changes are made to the
kernel file itself (/vmunix), so rebooting will undo any
modifications.  If you want to permanently change the value returned by
gethostid/sysinfo, one way to do this is to put the script output
by hid in /etc/rc.local

This overwrites two key instructions in the gethostid routine in the
memory image of the kernel (the kernel itself on disk is NOT modified)

the original instructions that are overwritten are
_gethostid+4:   call    _machineid
_gethostid+8:   nop

If you want the hostid
b0b1fb0b
hid outputs the script

adb -w -k /vmunix /dev/mem <<END
_gethostid+4/W 112c2c7e
_gethostid+8/W 9012230b
END

going to assembler
the new instructions are:
_gethostid+4:   sethi   %hi(0xb0b1f800), %o0
_gethostid+8:   or      %o0, 0x30b, %o0

basically 0x30b is the 10 rightmost bits of the desired
0xb0b1f800 is the 22 rightmost bits of the desired hostid

These two instructions set register o0 to the desired value, 
so it is as if machineid returned the desired hostid.

*/


#include <stdio.h>
main(argc,argv)
int argc;
char *argv[];
{
    unsigned int hid;
    unsigned int hi;
    unsigned int low;

    if (argc != 2) {
        fprintf(stderr, "usage: %s hostid\n",argv[0]);
        fprintf(stderr, "  e.g. %s b0b1fb0b\n", argv[0]);
        exit(1);
    }
    sscanf(argv[1],"%08x",&hid);

    hi = (hid & 0xfffffc00) >> 10;

    printf("#!/bin/sh\n");
    printf("# this script sets the hostid to %08x\n",hid);
    printf("adb -w -k /vmunix /dev/mem <<END\n");
    printf("_gethostid+4/W 11");
    printf("%06x\n", hi);

    low = hid & 0x3ff;
    printf("_gethostid+8/W 90122");
    printf("%03x\n",low);
    printf("END\n");
	return(0);
}
