#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>
#include <dos.h>
/* !!!!!!!!!!!!!! I didn't compile this version, so it might not be
   ready to run, I just put together parts of different sources to
   get it all in on file.

	- oct 1994

        btw my name is Willem Jan Hengeveld
        email itsme@xs4all.nl

    func & getnewlogkey  are internal server functions
      used to generate logkeys
    decode & decodepa are internal server functions
      used to get new password from a set password call

   encryptp : create encrypted password from userid, and password
   getpassk : create login data from encrypted password & logkey
   encrypt3 : create change pw date from login data for old pw +
              encrypted new pw
   decodepa : recreate encrypted pw from change pw data + old login data

*/

#define MAXPWLEN 64
#define MAXNAMELEN 48
typedef unsigned char u_char;

u_char tab0[256]=  /* used by encrypt */
{/* 0   1   2   3   4   5   6   7   8   9   a   b   c   d   e   f  */
   0x7,0x8,0x0,0x8,0x6,0x4,0xE,0x4,0x5,0xC,0x1,0x7,0xB,0xF,0xA,0x8,
   0xF,0x8,0xC,0xC,0x9,0x4,0x1,0xE,0x4,0x6,0x2,0x4,0x0,0xA,0xB,0x9,
   0x2,0xF,0xB,0x1,0xD,0x2,0x1,0x9,0x5,0xE,0x7,0x0,0x0,0x2,0x6,0x6,
   0x0,0x7,0x3,0x8,0x2,0x9,0x3,0xF,0x7,0xF,0xC,0xF,0x6,0x4,0xA,0x0,
   0x2,0x3,0xA,0xB,0xD,0x8,0x3,0xA,0x1,0x7,0xC,0xF,0x1,0x8,0x9,0xD,
   0x9,0x1,0x9,0x4,0xE,0x4,0xC,0x5,0x5,0xC,0x8,0xB,0x2,0x3,0x9,0xE,
   0x7,0x7,0x6,0x9,0xE,0xF,0xC,0x8,0xD,0x1,0xA,0x6,0xE,0xD,0x0,0x7,
   0x7,0xA,0x0,0x1,0xF,0x5,0x4,0xB,0x7,0xB,0xE,0xC,0x9,0x5,0xD,0x1,
   0xB,0xD,0x1,0x3,0x5,0xD,0xE,0x6,0x3,0x0,0xB,0xB,0xF,0x3,0x6,0x4,
   0x9,0xD,0xA,0x3,0x1,0x4,0x9,0x4,0x8,0x3,0xB,0xE,0x5,0x0,0x5,0x2,
   0xC,0xB,0xD,0x5,0xD,0x5,0xD,0x2,0xD,0x9,0xA,0xC,0xA,0x0,0xB,0x3,
   0x5,0x3,0x6,0x9,0x5,0x1,0xE,0xE,0x0,0xE,0x8,0x2,0xD,0x2,0x2,0x0,
   0x4,0xF,0x8,0x5,0x9,0x6,0x8,0x6,0xB,0xA,0xB,0xF,0x0,0x7,0x2,0x8,
   0xC,0x7,0x3,0xA,0x1,0x4,0x2,0x5,0xF,0x7,0xA,0xC,0xE,0x5,0x9,0x3,
   0xE,0x7,0x1,0x2,0xE,0x1,0xF,0x4,0xA,0x6,0xC,0x6,0xF,0x4,0x3,0x0,
   0xC,0x0,0x3,0x6,0xF,0x8,0x7,0xB,0x2,0xD,0xC,0x6,0xA,0xA,0x8,0xD
};

u_char tab[32]=   /* used by encrypt & encryptp */
{
  0x48,0x93,0x46,0x67,0x98,0x3D,0xE6,0x8D,0xB7,0x10,0x7A,0x26,0x5A,0xB9,0xB1,0x35,
  0x6B,0x0F,0xD5,0x70,0xAE,0xFB,0xAD,0x11,0xF4,0x47,0xDC,0xA7,0xEC,0xCF,0x50,0xC0
};

u_char tab1[8][2][16]=  /* used by encrypt3 */
{ /* 0   1   2   3   4   5   6   7   8   9   a   b   c   d   e   f  */
 {{ 0xF,0x8,0x5,0x7,0xC,0x2,0xE,0x9,0x0,0x1,0x6,0xD,0x3,0x4,0xB,0xA},
  { 0x2,0xC,0xE,0x6,0xF,0x0,0x1,0x8,0xD,0x3,0xA,0x4,0x9,0xB,0x5,0x7}},
 {{ 0x5,0x2,0x9,0xF,0xC,0x4,0xD,0x0,0xE,0xA,0x6,0x8,0xB,0x1,0x3,0x7},
  { 0xF,0xD,0x2,0x6,0x7,0x8,0x5,0x9,0x0,0x4,0xC,0x3,0x1,0xA,0xB,0xE}},
 {{ 0x5,0xE,0x2,0xB,0xD,0xA,0x7,0x0,0x8,0x6,0x4,0x1,0xF,0xC,0x3,0x9},
  { 0x8,0x2,0xF,0xA,0x5,0x9,0x6,0xC,0x0,0xB,0x1,0xD,0x7,0x3,0x4,0xE}},
 {{ 0xE,0x8,0x0,0x9,0x4,0xB,0x2,0x7,0xC,0x3,0xA,0x5,0xD,0x1,0x6,0xF},
  { 0x1,0x4,0x8,0xA,0xD,0xB,0x7,0xE,0x5,0xF,0x3,0x9,0x0,0x2,0x6,0xC}},
 {{ 0x5,0x3,0xC,0x8,0xB,0x2,0xE,0xA,0x4,0x1,0xD,0x0,0x6,0x7,0xF,0x9},
  { 0x6,0x0,0xB,0xE,0xD,0x4,0xC,0xF,0x7,0x2,0x8,0xA,0x1,0x5,0x3,0x9}},
 {{ 0xB,0x5,0xA,0xE,0xF,0x1,0xC,0x0,0x6,0x4,0x2,0x9,0x3,0xD,0x7,0x8},
  { 0x7,0x2,0xA,0x0,0xE,0x8,0xF,0x4,0xC,0xB,0x9,0x1,0x5,0xD,0x3,0x6}},
 {{ 0x7,0x4,0xF,0x9,0x5,0x1,0xC,0xB,0x0,0x3,0x8,0xE,0x2,0xA,0x6,0xD},
  { 0x9,0x4,0x8,0x0,0xA,0x3,0x1,0xC,0x5,0xF,0x7,0x2,0xB,0xE,0x6,0xD}},
 {{ 0x9,0x5,0x4,0x7,0xE,0x8,0x3,0x1,0xD,0xB,0xC,0x2,0x0,0xF,0x6,0xA},
  { 0x9,0xA,0xB,0xD,0x5,0x3,0xF,0x0,0x1,0xC,0x8,0x7,0x6,0x4,0xE,0x2}}
};

u_char tab3[16]=    /* used by encrypt3 */
  { 0x3,0xE,0xF,0x2,0xD,0xC,0x4,0x5,0x9,0x6,0x0,0x1,0xB,0x7,0xA,0x8 };

u_char tab8[8][2][16]= /* used by decode */
{
 {{0x8,0x9,0x5,0xC,0xD,0x2,0xA,0x3,0x1,0x7,0xF,0xE,0x4,0xB,0x6,0x0},
  {0x5,0x6,0x0,0x9,0xB,0xE,0x3,0xF,0x7,0xC,0xA,0xD,0x1,0x8,0x2,0x4}},
 {{0x7,0xD,0x1,0xE,0x5,0x0,0xA,0xF,0xB,0x2,0x9,0xC,0x4,0x6,0x8,0x3},
  {0x8,0xC,0x2,0xB,0x9,0x6,0x3,0x4,0x5,0x7,0xD,0xE,0xA,0x1,0xF,0x0}},
 {{0x7,0xB,0x2,0xE,0xA,0x0,0x9,0x6,0x8,0xF,0x5,0x3,0xD,0x4,0x1,0xC},
  {0x8,0xA,0x1,0xD,0xE,0x4,0x6,0xC,0x0,0x5,0x3,0x9,0x7,0xB,0xF,0x2}},
 {{0x2,0xD,0x6,0x9,0x4,0xB,0xE,0x7,0x1,0x3,0xA,0x5,0x8,0xC,0x0,0xF},
  {0xC,0x0,0xD,0xA,0x1,0x8,0xE,0x6,0x2,0xB,0x3,0x5,0xF,0x4,0x7,0x9}},
 {{0xB,0x9,0x5,0x1,0x8,0x0,0xC,0xD,0x3,0xF,0x7,0x4,0x2,0xA,0x6,0xE},
  {0x1,0xC,0x9,0xE,0x5,0xD,0x0,0x8,0xA,0xF,0xB,0x2,0x6,0x4,0x3,0x7}},
 {{0x7,0x5,0xA,0xC,0x9,0x1,0x8,0xE,0xF,0xB,0x2,0x0,0x6,0xD,0x3,0x4},
  {0x3,0xB,0x1,0xE,0x7,0xC,0xF,0x0,0x5,0xA,0x2,0x9,0x8,0xD,0x4,0x6}},
 {{0x8,0x5,0xC,0x9,0x1,0x4,0xE,0x0,0xA,0x3,0xD,0x7,0x6,0xF,0xB,0x2},
  {0x3,0x6,0xB,0x5,0x1,0x8,0xE,0xA,0x2,0x0,0x4,0xC,0x7,0xF,0xD,0x9}},
 {{0xC,0x7,0xB,0x6,0x2,0x1,0xE,0x3,0x5,0x0,0xF,0x9,0xA,0x8,0x4,0xD},
  {0x7,0x8,0xF,0x5,0xD,0x4,0xC,0xB,0xA,0x0,0x1,0x2,0x9,0x3,0xE,0x6}}
};

u_char tab9[16]=       /* used by decode */
  { 0xA,0xB,0x3,0x0,0x6,0x7,0x9,0xD,0xF,0x8,0xE,0xC,0x5,0x4,0x1,0x2 };

struct tod {  u_char
  curryear,
  currmont,
  currday ,
  currhour,
  currminu,
  currseco,
  currweek;
} tod;

int zeroseed=0;
int seed1=0,seed2=0;

/*
   seed1 : *2 mod 947   -> cycle length 946
   seed2 : *2 mod 941   -> cycle length 940
      together :  946*940=889240=8* 111155 = 2^3*5*11*43*47

  915  220       0
  184  570       825   *
  484  460       5102  *
  945    2       6858
  505  251       7936
  191  563      20053
  347  408      49641
  317  626      50319
  791  155      52249
   91  286      59015 *
  504  252      63514
    3  938      74552
  663   94      75630
  932  109      82524 *
  741  487      91346 *
  476  468     104818
  611  773     106975 ***
  915  220     111155
*/

u_char func(int c)
{
    if (seed1==0)
  {
    seed1=(tod.currmont<<4) + tod.currseco;
    zeroseed++;
  }
  else
    seed1<<=1;

  if (seed1>=947)
    seed1-=947;

  if (seed2==0)
  {
    seed2=(tod.currday<<3) + tod.currminu;
    zeroseed++;
  }
  else
    seed2<<=1;

  if (seed2>=941)
    seed2-=941;

  return (((u_char *)&tod)[(seed1+seed2)%7] +seed1+seed2+c)&0xff;
}

int newlogkey(int c, u_char *buf)
{
  u_char *p;  int i;
/*
       **** logkey[c]  is a table indexed by connection number
  if (logkey[c]==0)
  {
    logkey[c]=salloc(8);
    if (logkey[c]==0)
      return(0x96);  /* server out of memory */
  }

  p=logkey[c];
*/
  p=buf;
  for (i=0 ; i<8 ; i++)
    *p++=func(c);
/*  memcpy(logkey[c],buf,8);  */
  return(0);
}

unsigned int iswap(unsigned int nr)
{
  _AH = *((char *) &nr);
  _AL = *(((char *) &nr)+1);
}

unsigned long lswap(long l)
{
  _DH = *((char *) &l);
  _DL = *(((char *) &l)+1);
  _AH = *(((char *) &l)+2);
  _AL = *(((char *) &l)+3);
}

void dump(u_char *p,int l)
{
  int i;
  for (i=0 ; i<l ; i++)
    printf("%02x ",p[i]);
}

/* leaves p & src intact
 *  char p[8]    : part of old encrypted password
 *  char src[8]  : part of change password data
 *  char dst[8]  : part of new encrypted password  (result)
 */
void decode(u_char *p, u_char *src, u_char *dst)
{
  int i,j;
  u_char buf[8];
  char c;

  memcpy(buf,src,8);
  for (i=0 ; i<16 ; i++)
  {
    memset(dst,0,8);
    for (j=0 ; j<16 ; j++)
    {
      if ((c=tab9[j])&1)
        c=buf[c/2]>>4;
      else
        c=buf[c/2]&0xf;
      if (j&1)
        dst[j/2]|=(c<<4);
      else
        dst[j/2]|=c;
    }
    memcpy(buf,dst,8);
    c=p[0];
    for (j=0 ; j<7 ; j++)
      p[j]=(p[j]>>4)|(p[j+1]<<4);
    p[7]=(p[7]>>4)|(c<<4);
    for (j=0 ; j<8 ; j++)
    {
      c=buf[j];
      buf[j] = p[j] ^ (tab8[j][0][c&0xf] | (tab8[j][1][c>>4] << 4));
    }
  }
  memcpy(dst,buf,8);
}

/*
 *  char p1[16]  : old encrypted password   : from bindery
 *  char p2[16]  : change password data     : from network
 *  char p3[16]  : new encrypted password  (result)
 */
void decodepa(u_char *p1, u_char *p2, u_char *p3)
{
  decode(p1,p2,p3);
  decode(p1+8,p2+8,p3+8);
}

/* char p1[32]  : password xored with ID and itself ...
 * char p2[16]  : encrypted password (result)
 */
void encrypt(register u_char *p1, u_char *p2)  /* changes both p1 & p2 */
{
  int j;
  int i;
  u_char a;
  u_char c=0;
  for (j=0 ; j<2 ; j++)
    for (i=0 ; i<32 ; i++)
    {
      a=(p1[(i+c)&0x1f] - tab[i]) ^ (p1[i]+c);
      c+=a;
      p1[i]=a;
    }
  memset(p2,0,16);
  for (i=0 ; i<32 ; i++)
    if (i&1)
      p2[i/2] |= tab0[p1[i]]<<4;
    else
      p2[i/2] |= tab0[p1[i]];
}

/* char id[4]    : UserID
 * char src[len] : unencrypted password
 * int len       : length of unencrypted password
 * char dst[16]  : encrypted password (result)
 */
void encryptp(long id, u_char *src, int len, u_char *dst)
{
  u_char buf[32];
  u_char *p;
  u_char *q=src;
  int i;
  for (p=q+len-1 ; *p--==0 && len ; len--)
    ;
  memset(buf,0,32);
  for ( ; len>=32 ; len-=32)
    for (i=0 ; i<32 ; q++, i++)
      buf[i] ^= *q;

  p=q;
  if (len>0)
    for (i=0 ; i<32 ; i++)
    {
      if (q+len==p)
      {
        p=q;
        buf[i]^=tab[i];
      }
      else
        buf[i]^=*p++;
    }

  for (i=0 ; i<32 ; i++)
    buf[i] ^= ((u_char *)&id)[i&3];

  encrypt(buf,dst);
}

/* char logkey[8] : (requested with int21,ax=e3, fn 17 from server)
 * char crpw[16]  : encrypted password (with encryptp)
 * char dst[8]    : login data (result)
 */
void getpassk(long *logkey, u_char *crpw, u_char *dst)
{
  u_char buf[32];
  int i,j;
  encryptp(logkey[0],crpw,16,buf);
  encryptp(logkey[1],crpw,16,buf+16);
  for (i=0, j=31 ; i<16 ; i++, j--)
    buf[i]^=buf[j];
  for (i=0 , j=15 ; i<8 ; i++, j--)
    dst[i]=buf[i]^buf[j];
}

/* char p1[8] : part of old encrypted pw
 * char p2[8] : part of new encrypted pw
 * char p3[8] : part of change pw data (result)
 */
void encrypt3(register u_char *p1, u_char *p2, u_char *p3)
{
  register int j;
  u_char c;
  u_char buf[8];
  int i;
  memcpy(buf,p2,8);
  for (i=0 ; i<16 ; i++)
  {
    for (j=0 ; j<8 ; j++)
    {
      c=buf[j]^p1[j];
      buf[j]= tab1[j][0][c&15] | (tab1[j][1][c>>4] <<4);
    }
    c=p1[7];
    for (j=7 ; j>0 ; j--)
      p1[j]=(p1[j]<<4) | (p1[j-1]>>4);
    p1[0]= (c>>4) | (p1[0]<<4);

    memset(p3,0,8);
    for (j=0 ; j<16 ; j++)
    {
      c= tab3[j];
      c= (tab3[j]&1) ? (buf[c/2]>>4) : (buf[c/2]&0xf) ;
      p3[j/2] |= (j&1) ? (c<<4) : c ;
    }
    memcpy(buf,p3,8);
  }
}

int shreq(int f, u_char *req, int rl, u_char *ans, int al)
{
  struct REGPACK r;
  r.r_cx=rl;
  r.r_dx=al;
  r.r_si=FP_OFF(req);
  r.r_di=FP_OFF(ans);
  r.r_ds=FP_SEG(req);
  r.r_es=FP_SEG(ans);
  r.r_ax=0xf200|f;
  intr(0x21,&r);
  return(r.r_ax&0xff);
}

int getlogkey(u_char *s)
{
  u_char req[3];
  req[0]=0; req[1]=1; req[2]=0x17;
  return(shreq(0x17,req,3,s,8));
}

int getobjid(char *name, int type, long *id)
{
  u_char req[MAXNAMELEN+6];
  u_char rep[MAXNAMELEN+6];
  int err;
  req[2]=0x35;
  *(int *)(req+3)=type;
  req[5]=strlen(name);
  strncpy((char *)req+6,name,MAXNAMELEN);
  req[0]=0;
  req[1]=req[5]+4;
  err=shreq(0x17,req,req[1]+2,rep,MAXNAMELEN+6);
  *id=*(long *)rep;
  return(err);
}

int setpwcrypt(u_char *oldpw, int type, char *name, u_char *newpw, int l)
{
  u_char req[MAXNAMELEN+31];  /* 8+16(pw's) + 1 + 3(type+len) + 3(header) */
  req[2]=0x4b;
  memcpy(req+3,oldpw,8);
  *(int *)(req+11)=type;
  req[13]=strlen(name);
  strncpy((char *)req+14,name,48);
  req[14+req[13]]=l;
  memcpy(req+15+req[13],newpw,16);
  req[0]=0;
  req[1]=29+req[13];
  return(shreq(0x17,req,req[1]+2,req,0));
}

setpw(char *name, int type, char *oldpw, char *newpw)
{
  u_char req[8+MAXNAMELEN+2*MAXPWLEN];
  int l=5;
  req[2]=0x40;
  *(int *)(req+3)=type;
  req[l++]=strlen(name);
  strncpy((char *)req+l,name,MAXNAMELEN);
  l+=req[l];
  req[l++]=strlen(newpw);
  strncpy((char *)req+l,newpw,MAXPWLEN);
  l+=req[l];
  req[l++]=strlen(oldpw);
  strncpy((char *)req+l,oldpw,MAXPWLEN);
  l+=req[l];
  req[0]=l>>8; req[1]=l&0xff;
  return(shreq(0x17,req,l+2,req,0));
}

int changepw(char *name, int type, char *oldpw, char *newpw)
{
  u_char logkey[8];
  long id;
  u_char oldcrpw[16];
  u_char newcrpw[16];
  int err;
  int l;
  if (getlogkey(logkey)==0)
  {
    err=getobjid(name,type,&id);
    if (err)
      return (err);
    encryptp(id,(u_char *)oldpw,strlen(oldpw),oldcrpw);
    encryptp(id,(u_char *)newpw,strlen(newpw),newcrpw);
    getpassk((long *)logkey,oldcrpw,logkey);
    encrypt3(oldcrpw,newcrpw,newcrpw);
    encrypt3(oldcrpw+8,newcrpw+8,newcrpw+8);
    l=((( min(63,strlen(newpw))^oldcrpw[0]^oldcrpw[1] )&0x7f)|0x40);

    return(setpwcrypt(logkey,type,name,newcrpw,l));
  }
  else
    return(setpw(name,type,oldpw,newpw));
}

int trypw(char *pw, int type, char *name)
{
  u_char req[7+MAXNAMELEN+MAXPWLEN];
  req[2]=0x3f;
  *(int *)(req+3)=type;
  req[5]=strlen(name);
  strncpy((char *)req+6,name,MAXNAMELEN);
  req[6+req[5]]=strlen(pw);
  strncpy((char *)req+7+req[5],pw,MAXPWLEN);
  req[0]=0;
  req[1]=5+req[5]+req[6+req[5]];
  return(shreq(0x17,req,req[1]+2,req,0));
}

int trypwcrypt(u_char *crpw, int type, char *name)
{
  u_char req[14+MAXNAMELEN];
  req[2]=0x4a;
  memcpy(req+3,crpw,8);
  *(int *)(req+11)=type;
  req[13]=strlen(name);
  strncpy((char *)req+14,name,MAXNAMELEN);
  req[0]=0;
  req[1]=12+req[13];
  return(shreq(0x17,req,req[1]+2,req,0));
}

int testpw(char *name, int type, char *pw)
{
  u_char logkey[8];
  long id;
  u_char crpw[16];
  int err;
  if (getlogkey(logkey)==0)
  {
    err=getobjid(name,type,&id);
    if (err)
      return (err);
    encryptp(id,(u_char *)pw,strlen(pw),crpw);
    getpassk((long *)logkey,crpw,logkey);
    return(trypwcrypt(logkey,type,name));
  }
  else
    return(trypw(name,type,pw));
}

int logincrypt(u_char *crpw, int type, char *name)
{
  u_char req[14+MAXNAMELEN];
  req[2]=0x18;
  memcpy(req+3,crpw,8);
  *(int *)(req+11)=type;
  req[13]=strlen(name);
  strncpy((char *)req+14,name,MAXNAMELEN);
  req[0]=0;
  req[1]=12+req[13];
  return(shreq(0x17,req,req[1]+2,req,0));
}

int login(char *name, int type, char *pw)
{
  u_char req[7+MAXNAMELEN+MAXPWLEN];
  req[2]=0x14;
  *(int *)(req+3)=type;
  req[5]=strlen(name);
  strncpy((char *)req+6,name,MAXNAMELEN);
  req[6+req[5]]=strlen(pw);
  strncpy((char *)req+7+req[5],pw,MAXPWLEN);
  req[0]=0;
  req[1]=5+req[5]+req[6+req[5]];
  return(shreq(0x17,req,req[1]+2,req,0));
}

int dologin(char *name, int type, char *pw)
{
  u_char logkey[8];
  long id;
  u_char crpw[16];
  int err;
  if (getlogkey(logkey)==0)
  {
    err=getobjid(name,type,&id);
    if (err)
      return (err);
    encryptp(id,(u_char *)pw,strlen(pw),crpw);
    getpassk((long *)logkey,crpw,logkey);
    return(logincrypt(logkey,type,name));
  }
  else
    return(login(name,type,pw));
}

int setconn(int c)
{
  struct REGPACK r;
  r.r_ax=0xf000;  /* set preferred connection nr */
  r.r_dx=c+1;
  intr(0x21,&r);
  return(r.r_ax&0xff);
}

int scanobj(char *name, int *type, long *id, int *err)
{
  u_char req[10+MAXNAMELEN];
  /*  int length
   *  char type
   *  long id  (-1 for wildcard)
   *  int type (-1 for wildcard)
   *  char len
   *  char objname[len]
   */
  u_char rep[9+MAXNAMELEN];
  /*  long id              0
   *  int type             4
   *  char name[48]        6
   *  char object_flags    54
   *  char security_flags  55
   *  char more            56
   */
  int objlen=strlen(name);
  req[2]=0x37;   /* scan object list */
  *(long *)(req+3)=*id;
  *(int *)(req+7)=*type;
  req[9]=objlen;    /* string : obj name */
  strncpy((char *)req+10,name,MAXNAMELEN);
  req[0]=0; req[1]=8+objlen;
  *err=shreq(0x17, req, req[1]+2+(req[0]<<8), rep, 0x39);
  if (*err) return(0);

  strncpy(name,(char *)rep+6,MAXNAMELEN);
  *type=*(int *)(rep+4);
  *id=*(long *)rep;
  return(rep[56]);
}

void main(int argc, char **argv)
{
  char pw[MAXPWLEN];
  char newpw[MAXPWLEN];
  int err;
  int i;
  err=setconn(0);
  if (err)
    printf("failed setconn : %02x\n",err);
  if (argc>3)
  {
    debug=atoi(argv[1]);
    argv++;
    argc--;
  }
  if (argc<3)
  {
    printf("Usage : nov F username\n");
    printf("  F = t l s\n");
    exit(1);
  }
  strupr(argv[2]);
  while (kbhit()) getch();
  switch(argv[1][0])
  {
    case 't':   /* verifybinderyovbjectpassword */
      strcpy(pw,strupr(getpass("enter pw : ")));
      do {
        err=testpw(argv[2],0x100,pw);
        printf("%02x",err);
      } while (argv[1][1] && !kbhit());
      break;
    case 'l':   /* loginbinderyobject */
      strcpy(pw,strupr(getpass("enter pw : ")));
      do {
        err=dologin(argv[2],0x100,pw);
        printf("%02x",err);
      } while (argv[1][1] && !kbhit());
      break;
    case 's':    /* setbinderyobjectpassword */
      strcpy(pw,strupr(getpass("enter old pw : ")));
      strcpy(newpw,strupr(getpass("enter new pw : ")));
      do {
        err=changepw(argv[2],0x100,pw,newpw);
        printf("%02x",err);
      } while (argv[1][1] && !kbhit());
      break;

  }
  while (kbhit()) getch();
}
