/**********************************************************
 * users.c
 * version 2.0 - list users full name
 * version 2.1 - added switch and group info
 */

/*************************************************************
 * usage:
 *  users           - lists all members
 *  users  /a       - lists all members and their info
 *  users user name - lists info on a member
 */


#include <stdio.h>
#include <dos.h>
#include <ctype.h>

char myname[] = "Patrick L. McGillan";
char mydate[] = "November 24, 1989";
char myvers[] = "Users Version 2.1";

struct REGPACK Regs;

typedef unsigned char BYTE;

typedef struct {
		 unsigned char ah, al, bh, bl;
               } LONG;

typedef struct {
		 char wh, wl;
               } WORD;

typedef struct {
		 char wl, wh;
               } NATIVE;

typedef struct {                    /* send packet format for e3(36h)	*/
		 NATIVE SL;         /* packet length                    */
                 BYTE   FNC;  	    /*  $36 for get object name  	*/
		 LONG   UOID;       /*  Unique ID for the object 	*/
               } e336cl;

typedef struct {                    /* return packet format for e3(36h)	*/
		 NATIVE RL;         /* return length		        */
		 LONG   UOID;       /*  same id as above                */
		 WORD   OT;         /*  type of object                  */
		 BYTE   ON[48];
               } e336rp;

typedef struct {                    /* send packet format for e3(46h)   */
		 NATIVE SL;         /* send packet length               */
		 BYTE   FNC;        /*  $46 = get  bindery access level */
               } chkcall;

typedef struct {                    /* return packet format for e3(36h) */
		 NATIVE RL;         /* return length                    */
                 BYTE   AL;         /* access level allowed             */
		 LONG   MOID;       /* My Object ID                     */
               } chkrply;

typedef struct {                    /* send packet format for e3(37h)   */
		 NATIVE SL;         /* send packet length               */
		 BYTE   FNC;        /*  55 for Search for Users         */
		 LONG   LOS;        /*  make it -1                      */
		 WORD   PT;         /*  Search for users 0001           */
		 BYTE   PL;         /*  1                               */
		 BYTE   SP[48];     /*  *, if search all is used        */
               } e33dcall;

typedef struct {                    /* return packet format for e3(37h) */
		 NATIVE RL;         /* return packet length             */
		 LONG   UOID;       /* unique object id code            */
		 WORD   OT;         /* object type                      */
		 BYTE   ON[48];     /* object name                      */
                 BYTE   OF;         /* objects flags                    */
                 BYTE   OS;         /* objects security                 */
                 BYTE   PE;         /* properties exist                 */
             }  e33drply;

typedef struct {                    /* send packet format for e3(3dh)   */
		 NATIVE SL;         /* send packet length               */
		 BYTE   FNC;        /* 55 for Search for Users          */
		 WORD   OT;         /* object type                      */
		 BYTE   ONL;        /* object name length               */
		 BYTE   ON[48];     /* object name                      */
                 BYTE   SN;         /* segment number                   */
                 BYTE   PNL;        /* property name length             */
		 BYTE   PN[48];     /* property name                    */
               } e33prvcall;

typedef struct {                    /* return packet format for e3(3dh) */
		 NATIVE RL;         /* return packet length             */
		 BYTE   DT[128];    /* data                             */
                 BYTE   MR;         /* more                             */
                 BYTE   PF;         /* property flags                   */
             }  e33prvrply;


typedef struct {                    /* send packet format for e3(36h)   */
                 NATIVE SL;
                 BYTE   FNC;
                 LONG   UOID;
               } e33gncall;


typedef struct {
                 NATIVE RL;
                 LONG   UOID;
                 WORD   OT;
                 BYTE   ON[48];
               } e33gnrply;

e33gncall   gnc;
e33gnrply   gnr;

e336cl       nc;
e336rp       nr;

chkcall      cc;
chkrply      cr;

e33dcall     pc;
e33drply     pr;

e33prvcall   vc;
e33prvrply   vr;

void Users (nam)
char *nam;
{
    unsigned int SBO;
    int     i, once = 0, first = 1, all = 0;

    if (strlen(nam) < 1)
        strcpy (nam, "*");
    else
    {
        all = 1;
        once = 1;
    }

    if ((strcmp("/a", nam) == 0) || (strcmp("/A", nam) == 0))
    {
        strcpy (nam, "*");
        all = 1;
        once = 0;
    }

    do
    {
        SBO = scan_bind(first, nam);
        if ((SBO & 0x00ff) == 0)
        {
            printf ("\n\n%s", pr.ON);
            for (i=(12-strlen(pr.ON));i>0;--i)
                printf (" ");
            prntbyt (pr.UOID.ah);
            prntbyt (pr.UOID.al);
            prntbyt (pr.UOID.bh);
            prntbyt (pr.UOID.bl);
            print_name (pr.ON);
            if (all)
                tell_all (pr.ON);
        }
        first = 0;
    } while (((SBO & 0x00ff) == 0) && (!once));
}


scan_bind (first, nam)
int first;
char *nam;
{
    if (first)
    {
        pc.LOS.ah = 0x1f;   /*  set the last object seen to -1  */
        pc.LOS.al = 0xff;
        pc.LOS.bh = 0xff;
        pc.LOS.bl = 0xff;
    }
    else
    {
        pc.LOS.ah = pr.UOID.ah;   /*  set the last object seen to   */
        pc.LOS.al = pr.UOID.al;   /*  the last object seen */
        pc.LOS.bh = pr.UOID.bh;
        pc.LOS.bl = pr.UOID.bl;
    }
            
    pr.RL.wh = 0;
    pr.RL.wl = 57;

    pc.SL.wh = 0;
    pc.SL.wl = 58;

    pc.FNC = 0x37;   /*  scan bindery objects  */

    pc.PT.wh = 0;
    pc.PT.wl = 1;

    pc.PL = 48;

    strcpy (pc.SP, nam);

    Regs.r_ax = 0xE300;

    Regs.r_es = FP_SEG (&pr);
    Regs.r_di = FP_OFF (&pr);

    Regs.r_ds = FP_SEG (&pc);
    Regs.r_si = FP_OFF (&pc);

    intr (33, &Regs);

    return (Regs.r_ax);
}



print_name (name)
char *name;
{
    unsigned int RPV;

    vr.RL.wh = 0;            
    vr.RL.wl = 130;

    vc.SL.wh = 0;
    vc.SL.wl = 102;

    vc.FNC = 0x3d;

    vc.OT.wh = 0;
    vc.OT.wl = 1;

    vc.SN = 1;

    vc.ONL = 48;
    vc.PNL = 48;

    strcpy (vc.ON, name);
    strcpy (vc.PN, "IDENTIFICATION");

    Regs.r_ax = 0xE300;

    Regs.r_es = FP_SEG (&vr);
    Regs.r_di = FP_OFF (&vr);

    Regs.r_ds = FP_SEG (&vc);
    Regs.r_si = FP_OFF (&vc);

    intr (33, &Regs);
    RPV = Regs.r_ax;

    if ((RPV & 0x00ff) == 0)
        printf ("  %s", vr.DT);

}



prntbyt(value)
BYTE value;
{
    if (value == 0)
        printf ("00");
    else if (value < 0x10)
        printf ("0%X", value);
    else
        printf ("%X", value);
}



tell_all (name)
char *name;
{
    unsigned int RPV;
    int infirst = 1;

    printf ("\nBelongs to groups:");
    
    do
    {
        vr.RL.wh = 0;            
        vr.RL.wl = 130;

        vc.SL.wh = 0;
        vc.SL.wl = 102;

        vc.FNC = 0x3d;

        vc.OT.wh = 0;
        vc.OT.wl = 1;

        if (infirst)
        {
            vc.SN = 1;
            infirst = 0;
        }
        else
            vc.SN = vc.SN + 1;

        vc.ONL = 48;
        vc.PNL = 48;

        strcpy (vc.ON, name);
        strcpy (vc.PN, "GROUPS_I'M_IN");

        Regs.r_ax = 0xE300;

        Regs.r_es = FP_SEG (&vr);
        Regs.r_di = FP_OFF (&vr);

        Regs.r_ds = FP_SEG (&vc);
        Regs.r_si = FP_OFF (&vc);

        intr (33, &Regs);
        RPV = Regs.r_ax;

        if ((RPV & 0x00ff) == 0)
            get_name(vr.DT);

    } while ((vr.MR == 0xff) && ((RPV & 0x00ff) == 0));
}


get_name(ids)
char *ids;
{
    unsigned int GON;
    int i = 0, j, k = 0;

    printf ("\n");

    do
    {
        gnr.RL.wh = 0;
        gnr.RL.wl = 54;

        gnc.SL.wh = 0;
        gnc.SL.wl = 5;

        gnc.FNC = 0x36;

        gnc.UOID.ah = ids[i++];
        gnc.UOID.al = ids[i++];
        gnc.UOID.bh = ids[i++];
        gnc.UOID.bl = ids[i++];

        Regs.r_ax = 0xE300;

        Regs.r_es = FP_SEG (&gnr);
        Regs.r_di = FP_OFF (&gnr);

        Regs.r_ds = FP_SEG (&gnc);
        Regs.r_si = FP_OFF (&gnc);

        intr (33, &Regs);
        GON = Regs.r_ax;

        if ((GON & 0x00ff) == 0)
        {
            printf ("  %s", gnr.ON);
            for (j=(12-strlen(gnr.ON));j>0;--j)
                printf (" ");
            if (k == 3)
            {
                printf ("\n");
                k = 0;
            }
            else
                ++k;
        }
    } while (i < 128);
}


void New_Netware ()
{
    Regs.r_ax = 0xE300;

    cc.SL.wh = 0x00;                /* request packet length	*/
    cc.SL.wl = 0x01;

    cr.RL.wh = 0x00;		/* reply packet length		*/
    cr.RL.wl = 0xff;

    cc.FNC = 0x46;

    cr.AL = 0x00;
    cr.MOID.al = 0x00;
    cr.MOID.ah = 0x00;
    cr.MOID.bl = 0x00;
    cr.MOID.bh = 0x00;

    Regs.r_es = FP_SEG (&cr);
    Regs.r_di = FP_OFF (&cr);

    Regs.r_ds = FP_SEG (&cc);
    Regs.r_si = FP_OFF (&cc);

    intr (33, &Regs);

    if ((cr.MOID.al == 0x00) && (cr.MOID.ah == 0x00) && (cr.MOID.bl == 0x00) && (cr.MOID.bh == 0x00))
    {
        printf ("This utility requires Advanced Netware to run.\n");
        exit();
    }
    if (cr.AL != 0x33)
    {
        printf ("You must have supervisor rights to use this program.\n");
        exit();
    }
}

void Logged_In ()
{
    Regs.r_ax = 0xE300;

    nr.RL.wh = 0x00;		/* set reply buffer to 256 */
    nr.RL.wl = 0xFF;

    nc.SL.wh = 0x00;	        /* packet request length = 5 */
    nc.SL.wl = 0x05;                /* char = 1  -  longs = 4    */

    Regs.r_es = FP_SEG (&nr);
    Regs.r_di = FP_OFF (&nr);

    Regs.r_ds = FP_SEG (&nc);
    Regs.r_si = FP_OFF (&nc);

    nc.FNC = 0x36;

    nc.UOID.ah = cr.MOID.ah;            /* use user id obtained earlier */
    nc.UOID.al = cr.MOID.al;
    nc.UOID.bh = cr.MOID.bh;
    nc.UOID.bl = cr.MOID.bl;

    intr (33, &Regs);

    if ((Regs.r_ax & 0x00ff) != 0)
    {
        printf ("You must be logged into the network to run this program.\n");
        exit();
    }
}


main (argc, argv)
int argc;
char *argv[];
{
    New_Netware ();

    Logged_In ();

    Users (strupr(argv[1]));
}
