/* getlogin for DOS */

/* NetWare code by Rich Braun @ Kronos, 1991/03/13 */
/* further hacking by Paul Eggert and Frank Whaley */
/* LAN Server/Manager & WfW code by Kai Uwe Rommel 1994/04/08 */

/* $Id: logindos.c,v 1.2 1992/01/06 03:18:25 eggert Exp $ */

#ifdef __32BIT__

/* dummy code for 32-bit mode */

char *getlogin()
{
  return (char *) 0;
}

#else

/* real code for 16-bit mode */

#include <dos.h>
#include <string.h>

void doscall(union REGS *regs)
{
  struct SREGS sregs;
  segread(&sregs);
  sregs.es = sregs.ds;
  int86x(0x21, regs, regs, &sregs);
}

/* ----- Novell NetWare ----- */

#pragma pack(1)

/* Get Connection Information E3(16) */

struct _gcireq 
{
  unsigned short len;
  unsigned char func;
  unsigned char number;
};

struct _gcirep 
{
  unsigned short len;
  unsigned long objectID;
  unsigned short objecttype;
  char objectname[48];
  unsigned char logintime[7];
  unsigned char reserved[39];
};

#pragma pack()

char *nw_getlogin()
{
  static struct _gcirep gcirep;
  static struct _gcireq gcireq;

  union REGS r;

  /* Load Get Connection Number function code.   */
  r.x.ax = 0xDC00;
  doscall(&r);

  if (0 < r.h.al && r.h.al <= 100)
  {
    /* If the connection number is in range 1-100,
     * invoke Get Connection Information to get the user name. */

    gcireq.len = sizeof(gcireq) - sizeof(gcireq.len);
    gcireq.func = 0x16;
    gcireq.number = r.h.al;
    gcirep.len = sizeof(gcirep) - sizeof(gcirep.len);

    r.h.ah = 0xE3;
    r.x.si = (unsigned short) &gcireq;
    r.x.di = (unsigned short) &gcirep;
    doscall(&r);

    if (r.h.al == 0) 
    {
      strlwr(gcirep.objectname);
      return gcirep.objectname[0] ? gcirep.objectname : 0;
    }
  }

  return 0;
}

/* ----- Microsoft LAN Manager, Windows for Workgroups, IBM LAN Server ----- */

#pragma pack(1)

struct wksta_info_10
{
  char _far *computername;
  char _far *username;
  char _far *langroup;
  unsigned char ver_major;
  unsigned char ver_minor;
  char _far *logon_domain;
  char _far *oth_domains;
  char filler[32];
};

#pragma pack()

char *lan_getlogin()
{
  static struct wksta_info_10 wksta;
  static char name[32];
  union REGS r;

  r.x.ax = 0x5F44;
  r.x.bx = 10;
  r.x.cx = sizeof(wksta);
  r.x.di = (unsigned short) &wksta;
  doscall(&r);

  if (r.x.ax == 0 || r.x.ax == 0x5F44)
  {
    _fstrcpy(name, wksta.username);
    strlwr(name);
    return name[0] ? name : 0;
  }

  return 0;
}

#ifdef TEST

/* ----- testing code ----- */

void main(void)
{
  printf("NetWare: <%s>\nLAN Manager: <%s>\n",
	 nw_getlogin(), lan_getlogin());
}

#else

/* ----- main entry point ----- */

char *getlogin()
{
  char *lm = lan_getlogin();
  char *nw = nw_getlogin();
  return lm ? lm : nw ? nw : (char *) 0;
}

#endif

#endif

