/*---------------------------------------------------------------------------*\
|   GET all Logon assignments from Server 3.0 and higher                      |
|   and dump it to an ASCII File                                              |
|       (C) Alain Rykaert IBM Belgium & Hermann Pauli IBM Germany SEP95-MAY96 |
\*---------------------------------------------------------------------------*/
                                   /* you may change this variables         */
    LUserId  = 8                   /* max.length of any user ID in your dom*/
                                   /* LS 2.0 and 3.0 LID <= 8, LS 4.0 <= 15 */
    MaxLines = 20                    /* max. number of lines between banner*/

    Parse Arg Option

    Call INIT                     /* Initalisation of DLL's and other stuff*/
    Call CHKOPT                          /* Check Options & display Welcome*/
    Call CHKPWS                               /* Check the PWS & Admin name*/
    Call MAIN                                            /* do the main job*/
    Call CHKERR                                         /* Check for errors*/
    Call QUIT                                                       /* Quit*/

 MAIN:/* ------------------------------------------------------ MAIN: -------*/

    Call Time('R')
   'if exist' OUTF 'del' OUTF

   /* get all defined groups */
    RC = NetEnumerate(NETGROUP, 'GroupInfo', '\\'SRVNAME)
    if RC <> 0
     then do
             Call LOGIT 'NetEnum. Group' , 'Server \\' || SRVNAME , RC
             Call quit
          end
     else call RxStemSort 'GroupInfo'

   /* prepare the output tables banner */
    Call GetBanner

   /* prepare the top of the output */
   'if exist' OUTF 'del' OUTF

    NumOut = 0 ; NumGrp = 0

   /* put info to outfile, sorted by Group and UserID */
    do i = 1 to GroupInfo.0
       /* decide whether this group will be covered or not :                 */
       /*     (groups SERVERS, GROUPID and LOCAL will always be ignored)     */
       /* if you selected show groups only   => ignore group USERS           */
       /* if you selected do not show groups => only ADMINS, GUESTS & USERS  */
       /*                                       else show ALL groups         */
       if (\ShowGrp & Translate(GroupInfo.i) <> 'USERS',
                    & Translate(GroupInfo.i) <> 'GUESTS',
                    & Translate(GroupInfo.i) <> 'ADMINS') |,
          (\ShowUsr & Translate(GroupInfo.i)  = 'USERS' ) |,
          (ShowGrp  & (Translate(GroupInfo.i) = 'SERVERS',
                     | Translate(GroupInfo.i) = 'GROUPID',
                     | Translate(GroupInfo.i) = 'LOCAL'))
        then iterate

       NumGrp = NumGrp + 1
       Call Lineout OUTF, ALIASLST
       Call Lineout OUTF, '* Members Of Group' GroupInfo.i

       RC = NetGetInfo(NETGROUPUSERS, 'USERID', '\\'SRVNAME, GroupInfo.i)
       if RC <> 0
        then do
                Call Logit 'NetGetInfo G/U' ,,
                           'Server \\' || SRVNAME USERID.i , RC
                Call Quit
             end
        else Call RxStemSort 'USERID'

       do j = 1 to USERID.0
          NumOut = NumOut + 1
          if j // MaxLines = 0
           then Call Lineout OUTF, ALIASLST
           else nop

          if \Trace
           then do
                   if ShowGrp
                    then say '0909'x ESC'[K Total Groups =' NumGrp 'Users =' j'/'UserID.0 USERID.j
                    else say '0909'x ESC'[K Total Users  =' NumOut '('j'/'UserID.0')' USERID.j
                   if \MUTE
                    then do
                            Call SysCurState OFF
                            parse value SysCurPos() with row col
                            row = row - 1
                            Call SysCurPos row,0
                         end
                    else Nop
                 end
           else say '0909'x NumOut ':' GroupInfo.i USERID.j

          W_ID = USERID.j
          OUT  = EmptyLst
          OUT  = OVERLAY(W_ID,OUT,5)

          RC = NetGetInfo(NETLOGONASN, 'LASSINFO', '\\'SRVNAME, USERID.j)
          if RC = 0
           then do
                   do k = 1 to LASSINFO.count
                      W_Alias  = LASSINFO.k.Alias
                      W_Device = LASSINFO.k.Device
                      Call PrepOut
                   end
                   Call LineOut OUTF, OUT
                end
           else if left(strip(RC),1) <> 3
                 then do
                         Call LOGIT 'NetGetInfo LA' , USERID.j , RC
                         call quit
                      end
                 else do                    /* no assignments for this user*/
                         W_Alias  = ''
                         Call PrepOut
                         Call LineOut OUTF, OUT
                      end
       end
       Call Lineout OUTF, ' '
    end

    if \MUTE then say '0A0D0909'x ' Total Time   =' Trunc(Time('E'),2)

    Call Stream OUTF, 'C', 'CLOSE'

    Call SysSetObjectData OUTF, 'ICONFILE='Directory()'\Assgn.Ico'

    Return

 PREPOUT:/* --------------------------------------------------- PREPOUT: ----*/

    if strip(W_Alias) <> ''
     then do
        if APos.W_Alias = 0
         then do
                 ErrAsgn = 1
              end
         else do
                 LCol  = POS(';',ALIASLST,APos.W_Alias) - APos.W_Alias
                 LAssT = CENTER(W_Device,Max(LCol,LENGTH(W_Device)))
                 OUT   = OVERLAY(LAssT,OUT,APos.W_Alias)
              end
     end
     else nop
    Return

 CHKERR:/* --------------------------------------------------- CHECKERR: ----*/

    if ErrAsgn
     then do
            Topic_List='CHKASSGN';
            Call GETANS
          end
     else nop
    Return

 GETBANNER:/* ------------------------------------------------- GETBANNER:---*/

    /* Get list of all aliases definend on server */
    RC = NetEnumerate(NETALIAS, 'ALIASFiles' , '\\'SRVNAME,1)
    if RC <> 0 & substr(RC,1,3) <> '234 '       /* 234 = no File Alias def.*/
     then do
             Call LOGIT 'NetEnumerate F-Alias' , 'Server \\' || SRVNAME , RC
             call quit
          end
     else call RxStemSort 'ALIASFiles'

    RC = NetEnumerate(NETALIAS, 'ALIASPrint' , '\\'SRVNAME,2)
    if RC <> 0 & substr(RC,1,3) <> '234 '       /* 234 = no File Alias def.*/
     then do
             Call LOGIT 'NetEnumerate P-Alias' , 'Server \\' || SRVNAME , RC
             call quit
          end
     else call RxStemSort 'ALIASPrint'

    RC = NetEnumerate(NETALIAS, 'ALIASSerial', '\\'SRVNAME,4)
    if RC <> 0 & substr(RC,1,3) <> '234 '       /* 234 = no File Alias def.*/
     then do
             Call LOGIT 'NetEnumerate S-Alias' , 'Server \\' || SRVNAME , RC
             call quit
          end
     else call RxStemSort 'ALIASSerial'

    ALIASLST = 'OPT'           || ';' || left('USERID',LUserId,' ') || ';'
    EmptyLst = left(' ',3,' ') || ';' || left(' ',LUserId,' ')      || ';'

    APos.   = 0                                 /* initialize all APos to 0*/
    do i=1 to ALIASFiles.0
       AN       = ALIASFiles.i
       APos.AN  = length(ALIASLST) + 1
       ALIASLST = ALIASLST || strip(AN) || ';'
       EmptyLst = EmptyLst || Left(' ',Length(AN),' ') || ';'
    end

    do i=1 to ALIASPrint.0
       AN       = ALIASPrint.i
       APos.AN  = length(ALIASLST) + 1
       ALIASLST = ALIASLST || Left(AN,Max(Length(AN),LMinAss),' ') || ';'
       EmptyLst = EmptyLst || Left(' '  ,Max(Length(AN),LMinAss),' ') || ';'
    end

    do i=1 to ALIASSerial.0
       AN       = ALIASSerial.i
       APos.AN  = length(ALIASLST) + 1
       ALIASLST = ALIASLST || Left(AN,Max(Length(AN),LMinAss),' ') || ';'
       EmptyLst = EmptyLst || Left(' '  ,Max(Length(AN),LMinAss),' ') || ';'
    end

    Return

 CHKOPT:/* ---------------------------------------------------- CHKOPT: -----*/

    SRVNAME = ''
    OUTF  = 'ASSGN.CSV'
    LOGF  = 'LSMT.LOG'
    PIPE  = ''
    TRACE = 0
    MUTE  = 0
    ShowGrp = 0
    ShowUsr = 1

    OPTION = Translate(OPTION)
    do while OPTION <> ''
       Parse value OPTION with ARGUMENT ' ' OPTION
       select
        when Left(ARGUMENT,5) = '/SRV:'  then SRVNAME = Substr(ARGUMENT,6)
        when Left(ARGUMENT,5) = '/OUT:'  then OUTF    = Substr(ARGUMENT,6)
        when Left(ARGUMENT,5) = '/LOG:'  then LOGF    = Substr(ARGUMENT,6)
        when Left(ARGUMENT,5) = '/PIP:'  then PIPE    = Substr(ARGUMENT,6)
        when Left(ARGUMENT,2) = '/M'     then MUTE    = 1
        when Left(ARGUMENT,2) = '/T'     then TRACE   = 1
        when Left(ARGUMENT,6) = '/GROUPS',
           | Left(ARGUMENT,2) = '/G'     then ShowGrp = 1
        otherwise Nop
       end
    end

    if SRVNAME = '' then signal GETHELP

    if \MUTE
     then do
             Topic1 = 'GETWELCOME'
             Topic2 = 'GETASSGN'
             Topic_String.Topic1.1 = SRVNAME;
             Topic_String.Topic1.2 = OUTF;
             Topic_String.Topic1.3 = LOGF;
             Topic_String.Topic1.4 = PIPE' ';
             if ShowGrp
                then ShowTxt = 'Yes'
                else ShowTxt = 'No '
             Topic_String.Topic2.1 = ShowTxt;
             Topic_List='WELCOMELOGO' Topic1 Topic2;
             Call GETANS
             Parse VALUE SysCurPos() With Old_R Old_C; 'Pause';
             Call SysCurPos Old_R, Old_C; say ESC'[K';
          end
     else do
             say 'ServerName =' SRVNAME
             say 'OutputFile =' OUTF
             say 'LogFile    =' LOGF
          end
    Return

 CHKPWS:/* ---------------------------------------------------- CHKPWS: -----*/

    RC = NetGetInfo(350, 'WKSTAINFO','')
    if RC = 0
     then do
             ADMNAME = WKSTAINFO.UserName
             PWSNAME = WKSTAINFO.ComputerName
          end
     else do
            Call LOGIT 'Get PWS Info', ,RC
            Call Quit
          end
    Return

 INIT:/* ------------------------------------------------------ INIT: -------*/

    Call RgUtil   '/m'                                    /* Rexx Utilities*/
    Call RgUtils  '/m'                                    /* Rexx Utilities*/
    Call RgNPipes '/m'                                       /* Named Pipes*/
    Call RgLSRXUT '/m'                             /* Lan Server Rexx Utils*/

    Parse Upper Source . . P_NAME
    PRGN = Filespec('N', Left(P_NAME, Length(P_NAME) -4))

   '@echo off'
    ESC     = '1B'x
    REDIR   = '>NUL 2>NUL'

    LMinAss = 5                     /* min. length for logon assignment col*/
    ErrAsgn = 0                                      /* no assignment error*/

    NETLOGONASN   = 52                               /* code for LSREXX API*/
    NETUSER       = 280
    NETGROUPUSERS = 340
    NETGROUP      = 70
    NETWKSTA      = 350
    NETALIAS      = 20

    Resource_File = 'LSMT.RSC'
    Call CHKFILE Resource_File

    Return

 GETANS:/* ---------------------------------------------------- GETANS: -----*/

    Vars_List =Ansi_Say(Resource_File Topic_List);
    Parse VALUE SysCurPos() With Old_R Old_C;
    Do While Vars_List <> '';
       Parse VALUE Vars_List With Topic_Id ';' Var_Id ';' Row ';' Column ';' Color ';' Vars_List;
       Call SysCurPos Row, Column;
       Say x2c(Color) || Topic_String.Topic_Id.Var_Id || '1B'x || '[0m';
       End;
    Call SysCurPos Old_R, Old_C;

    Return

 GETHELP:/* --------------------------------------------------- GETHELP: ----*/

    if \MUTE
     then do
             Topic1='GETASSGNHELP'
             Topic_String.Topic1.1=PRGN;
             Topic_List=Topic1;
             Call GETANS
          end
     else say 'Incorrect options.'

    Call QUIT

    Return

 CHKFILE:/* --------------------------------------------------- CHKFILE: ----*/

    Parse Arg FILE
    RC = Stream(FILE, 'C', 'QUERY EXIST')
    if RC = ''
     then do
             say ' File' FILE 'not found.'
             Call QUIT
          end
     else Nop
    Call Stream FILE, 'C', 'CLOSE'

    Return

 LOGIT:/* ----------------------------------------------------- LOGIT: ------*/

    FUNC = ARG(1); INFO = ARG(2); RCOD = ARG(3)
    RC = LLOGIT(LOGF, PIPE, ADMNAME, PRGN, FUNC, INFO, RCOD)

    Return

 QUIT:/* ------------------------------------------------------ QUIT: -------*/

    Call LineOut 'LSMT.END', PRGN, 1
    Call Stream  'LSMT.END', 'C', 'CLOSE'

    Call Stream   LOGF,      'C', 'CLOSE'
    Call Stream   OUTF,      'C', 'CLOSE'

    Exit

 /*--------------------------------------------------------------------------*/
