SDUMP.C
// --sdump.c------------------------------------------------------------------ 
// 
//  Dump an address template 
// 
//  Copyright (C) Microsoft Corp. 1986-1996.  All rights reserved. 
// 
// --------------------------------------------------------------------------- 
 
#include <stdio.h> 
#include <string.h> 
#include <stdarg.h> 
#include <stdlib.h> 
 
#define HALT    0L 
#define ERRX    1L 
#define EMIT    2L 
#define JUMP    3L 
#define JNX     4L 
#define JE      5L 
#define EMITUPPER    6L 
 
#define OP1_ADDR        0x80000000 
#define OP2_ADDR        0x40000000 
 
#define NUL     0 
#define OP      1 
#define ADR     2 
#define PROP    3 
 
int            i; 
unsigned long  *buf; 
 
void instruction(char *s, int type1, int type2, int type3); 
void operand(int type, int oper); 
 
// Main routine 
void main(int argc, char *argv[]) 
   { 
   int      n; 
   fpos_t   pos;                       
   FILE     *fh; 
    
   if (argc != 2) { printf("Microsoft Exchange Script Dump Version 1.0\n\nUsage: SDUMP FILE\n"); exit(1); } 
    
   // Read the script into the buffer 
   strupr(argv[1]); 
   if ((fh = fopen(argv[1], "rb")) == NULL) { printf("File \"%s\" not found!\n", argv[1]); exit(2); } 
   fseek(fh, 0l, SEEK_END);   // seek to eof 
   fgetpos(fh, &pos);         // get file length 
   fseek(fh, 0l, SEEK_SET);   // seek to beginning 
   n = (int)pos;              // file size 
   buf = malloc(n); 
   fread(buf, 1, n, fh) / sizeof(unsigned long); 
   fclose(fh); 
    
   printf("Script Dump of %s\n\n", argv[1]); 
    
   // Step through the script 
   while(i<n) 
      { 
      printf("%04X: ", i* sizeof(unsigned long)); 
      switch(buf[i] & 0xFL) 
         { 
         case HALT:  instruction("HALT", NUL, NUL, NUL); i = n; break; 
         case ERRX:  instruction("ERRX", NUL, NUL, NUL); break; 
         case EMIT:  instruction("EMIT",  OP, NUL, NUL); break; 
         case JUMP:  instruction("JUMP", ADR, NUL, NUL); break; 
         case JNX:   instruction("JNX",   OP, ADR, NUL); break; 
         case JE:    instruction("JE",    OP,  OP, ADR); break; 
         case EMITUPPER:  instruction("EMTU",  OP, NUL, NUL); break; 
         default:    instruction("<UNKNOWN>", NUL, NUL, NUL); break; 
         } 
      printf("\n"); 
      } 
   }              
 
// Dump out an instruction 
void instruction(char *s, int type1, int type2, int type3) 
   { 
   int   oper1, oper2; 
    
   // Test the modifier bits 
   if ((buf[i] & OP1_ADDR) == 0) oper1 = PROP; else oper1 = ADR; 
   if ((buf[i] & OP2_ADDR) == 0) oper2 = PROP; else oper2 = ADR; 
 
   printf("%-4s", s); i++;                   // Print the Instruction 
   if (type1 != NUL) operand(type1, oper1);  // Print the first operand 
   if (type2 != NUL) operand(type2, oper2);  // Print the second operand 
   if (type3 != NUL) operand(type3, ADR);    // Print the third operand 
   } 
 
// Dump out an operand 
void operand(int type, int oper) 
   { 
   // override the operand if the instruction type is an address 
   if (type == ADR) oper = ADR; 
    
   switch(oper) 
      { 
      case ADR:    
         if (type == ADR) printf(" %08lX", buf[i]);  
         else printf(" \"%s\"", (char *)buf + buf[i]); 
         break; 
          
      case PROP:   
         printf(" %04lX+%04lX", buf[i] >> 16, buf[i] & 0xFFFF);  
         break; 
      }          
   i++;  // Increment the instruction pointer 
   }