/* modify hostid reported by gethostid and sysinfo for Solaris 2.3 and 1.1
   dynamically linked binaries 
Placed in the public domain by the author 
Mark Henderson - mch@squirrel.com - 18 July 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.

New feature to be included in version 1.0 of the package: 18 July 1994
the environment variable HID can be set to the desired hostid in hex.
(no leading 0x, a-f lower case)

In retrospect, I should have written this in perl.

Instructions:

Solaris 1.x
1. compile this program
    cc -o sidump sidump.c
2. run it with the desired hostid as the first parameter and save the output
    in a file with the extension .c 
    ./sidump b0b1fb0b >foo.c
3. make foo.o from foo.c
      gcc -fpic -c foo.c
      ld foo.o  -assert pure-text -o foo.so
   OR
      cc -PIC -c foo.c
      ld foo.o -assert pure-text -o foo.so
4. export LD_PRELOAD=$PWD/foo.so      (ksh)
   setenv LD_PRELOAD $PWD/foo.so      (csh)
5. run the desired program

here's a sample session
feral> cc -o sidump sidump.c
feral> ./sidump b0b1fb0b >foo.c
feral> cc -PIC -c foo.c
feral> ld -assert pure-text foo.o -o foo.so
feral> export LD_PRELOAD=$PWD/foo.so
feral> lmhostid
feral> lmhostid - Copyright (C) 1989, 1991 Highland Software, Inc.
The FLEXlm host ID of this machine is "b0b1fb0b"
feral> export HID=72000000
feral> lmhostid
lmhostid - Copyright (C) 1989, 1991 Highland Software, Inc.
The FLEXlm host ID of this machine is "72000000"

--------------
Solaris 2.x

1. compile this program
    gcc -DSOLARIS2 -o sidump sidump.c
2. run it with the desired hostid as the first parameter and save the output
    in a file with the extension .c 
    ./sidump b0b1fb0b >foo.c
3. make foo.o from foo.c
      gcc -fpic -c foo.c
      ld foo.o  -G -o foo.so
4. export LD_PRELOAD=$PWD/foo.so      (ksh)
   setenv LD_PRELOAD $PWD/foo.so      (csh)
5. run the desired program

here's a sample session:

ratatosk> gcc -o sidump sidump.c
ratatosk> ./sidump b0b1fb0b >foo.c
ratatosk> gcc -fpic -c foo.c
ratatosk> ld foo.o  -G -o foo.so
ratatosk> export LD_PRELOAD=$PWD/foo.so
ratatosk> hostid
b0b1fb0b
ratatosk> lmhostid
lmhostid - Copyright (C) 1989, 1991 Highland Software, Inc.
The FLEXlm host ID of this machine is "b0b1fb0b"
ratatosk> export HID=72000000
ratatosk> lmhostid
lmhostid - Copyright (C) 1989, 1991 Highland Software, Inc.
The FLEXlm host ID of this machine is "72000000"


*/


#include <stdio.h>
#ifdef SOLARIS2
#include <sys/systeminfo.h>
int commands[] = {SI_HW_SERIAL, SI_SYSNAME,SI_HOSTNAME,
 SI_RELEASE,SI_VERSION,SI_MACHINE,SI_ARCHITECTURE,SI_HW_PROVIDER,
 SI_SRPC_DOMAIN};
#endif

#define NCOMMANDS (sizeof(commands)/sizeof(int))

main(argc,argv)
int argc;
char *argv[];
{
    int i,j;
    char buf[1024];
    unsigned int hostid;
    if (argc != 2) {
        fprintf(stderr, "usage: %s hostid\n", argv[0]);
        exit(1);
    }
    sscanf(argv[1], "%x", &hostid);
    printf("#include <string.h>\n");
    printf("#include <stdlib.h>\n");
    printf("extern char **environ;\n");
    printf("unsigned int xyzzy_ghid()\n");
    printf("{\n");
    printf("    int i,j,c; char **s; char *e;\n");
    printf("    unsigned int hid;\n");
    printf("    hid = 0;\n");
    printf("    s = environ;\n");
    printf("    for (; *s; s++) {\n");
    printf("        e = *s;\n");
    printf("        if (*e++ == \'H\' \n");
    printf("            && (*e++ == \'I\')\n");
    printf("            && (*e++ == \'D\')\n");
    printf("            && (*e++ == \'=\'))  {\n");
    printf("                for (j=28; (*e) && j>=0; j -=4 ) {\n");
    printf("                    c = (-1);\n");
    printf("                    if (*e >= \'0\' && *e <= \'9\') \n");
    printf("                        c = *e - \'0\';\n");
    printf("                    if (*e >= \'a\' && *e <= \'f\') \n");
    printf("                        c = *e - \'a\' + 10;\n");
    printf("                    e++;\n");
    printf("                    if (c == (-1))\n");
    printf("                        break;\n");
    printf("                    hid = hid | (c << j);\n");
    printf("                }\n");
    printf("            return hid;\n");
    printf("        }\n");
    printf("    }\n");
    printf("    return 0;\n");
    printf("}\n");
    printf("gethostid() { \n");
    printf("unsigned x;\n");
    printf("if (x=xyzzy_ghid()) \n");
    printf("{return x; }");
    printf("else return 0x%08x; }\n", hostid);
#ifdef SOLARIS2
    printf("long sysinfo(command,buf,count)\nint command;\nchar *buf;\n");
    printf("long count;\n{\nchar *c = buf; int i; unsigned int x,y;\n");
    printf("switch(command) { \n");
    printf("case %u:\n", commands[0]);
    sprintf(buf,"%u",hostid);  /* should this be %010u ??? */
    printf("if (!(x = xyzzy_ghid())) {\n");
    for (j=0; j < strlen(buf); j++)
        printf("if (c < (buf + count)) *c++ = '%c';\n", buf[j]);
    printf("if (c < (buf + count)) *c++ = 0;\n");
    printf("buf[count-1] = 0;\n");
    printf("}\n");
    printf("else {\n");
    printf("y = 1000000000;\n");
    printf("for (i=0; (i<10) && (i<count); i++) {\n");
    printf("buf[i] = (x/y) + '0'; x -= (x/y) * y;");
    printf("y/=10; }\n");
    printf("if (count < 11) buf[count - 1] = 0 ; else buf[10] = 0;}\n");
    printf("break;\n");
    for (i=1; i< NCOMMANDS; i++) {
        sysinfo(commands[i], buf,1024);
        printf("case %u:\n", commands[i]);
        for (j=0; j < strlen(buf); j++)
            printf("if (c < (buf + count)) *c++ = '%c';\n", buf[j]);
        printf("if (c < (buf + count)) *c++ = 0;\n");
        printf("buf[count-1] = 0;\n");
        printf("break;\n");
    }
    printf("default: \nreturn(-1); \n}\n");
    printf("return(strlen(buf) + 1);}\n");
#endif
	return(0);
}
