/****************************************************************/
/* Utility to retrieve a lost FtpServer password.               */
/*                                                              */
/*       Programmer:      P. Moylan                             */
/*       Last modified:   16 November March 2020                */
/*                                                              */
/*   Usage:    findpassword username                            */
/*                                                              */
/****************************************************************/

call RxFuncAdd 'SysLoadFuncs', 'RexxUtil', 'SysLoadFuncs'
call SysLoadFuncs
CALL CheckPrerequisites SelectTNI INI_get

parse arg username
DO WHILE username = ''
    CALL CharOut , 'Username: '
    PARSE PULL username
END

INIFile = INIFileFor(username)
IF INIFile = '' THEN
    DO
        SAY "No INI/TNI entry for username" username
        EXIT 1
    END
IF INI_get(INIFile, username) = '' THEN
    DO
        SAY "No such user "username
        EXIT 1
    END
IF INI_get(INIFile, username, 'EncryptPassword') = '01'X THEN
    DO
        SAY 'Sorry, the password has been encrypted and cannot be read.'
        EXIT 1
    END

password = INI_get(INIFile, username, 'Password')
SAY 'username = 'username
SAY 'password = 'password
EXIT 0

/****************************************************************/
/*  Procedure to find the INI or TNI file that contains the     */
/*  data for one user.  In many installations this will turn    */
/*  out to be FTPD.INI or FTPD.TNI, but if the option to use    */
/*  multiple INI files is activated then the file name is based */
/*  on a hash coding of the username.  We return an empty       */
/*  string if the file doesn't exist.                           */
/****************************************************************/

IniFileFor:  PROCEDURE

    PARSE UPPER ARG username
    IF SelectTNI("FTPD") THEN extension = "TNI"
    ELSE extension = "INI"
    HashMax = INI_get('FTPD.'extension, '$SYS', 'HashMax')
    IF HashMax = '' THEN HashMax = 0
    ELSE HashMax = C2D(REVERSE(HashMax))
    IF HashMax = 0 THEN code = ''
    ELSE DO
        code = 0
        DO WHILE username <> ''
            ch = LEFT(username,1)
            username = RIGHT(username, LENGTH(username)-1)
            code = (16*code + C2D(ch)) // HashMax
        END
        code = TRANSLATE(FORMAT(code,4), '0', ' ')
    END
    file = 'FTPD'code'.'extension

    /* Check whether the file exists. */

    IF STREAM(file, 'C', 'QUERY EXISTS') = '' THEN file = ''
    ELSE SAY "Using "file

    RETURN file

/****************************************************************/
/*                      CHECKING PREREQUISITES                  */
/****************************************************************/

CheckPrerequisites: PROCEDURE

    /* The argument is a space-separated list of prerequisite   */
    /* functions, for example                                   */
    /*      CALL CheckPrerequisites rxu SelectTNI INI_get       */
    /* where (at least in this version) each list item is       */
    /* either 'rxu' or a function from my TNItools package.     */
    /* If any is missing then we exit with an error message.    */

    PARSE UPPER ARG funclist
    funclist = STRIP(funclist)
    needrxu = 0
    needtools = 0
    DO WHILE funclist \= ''
        PARSE VAR funclist func funclist
        funclist = STRIP(funclist)
        IF func = 'RXU' THEN DO

            /* Initialise RXU if not already available, fail if */
            /* the RxFuncAdd operation fails.  We must          */
            /* RxFuncQuery RxuTerm because RxuTerm does not     */
            /* deregister RxuInit.  The RxFuncDrop is needed    */
            /* because RxFuncAdd seems to report failure if the */
            /* function is already registered.                  */

            IF RxFuncQuery('RxuTerm') THEN DO
                CALL RxFuncDrop('RxuInit')
                CALL RxFuncAdd 'RxuInit','RXU','RxuInit'
                IF result THEN DO
                    SAY 'Cannot load RXU'
                    needrxu = 1
                END
                ELSE CALL RxuInit
            END
        END
        ELSE DO
            func = func||'.CMD'
            IF SysSearchPath('PATH', func) = '' THEN DO
                SAY 'ERROR: 'func' must be in your PATH'
                needtools = 1
            END
        END
    END
    IF needrxu THEN SAY 'You can find RXU1a.zip at Hobbes'
    IF needtools THEN SAY 'Please install the GenINI package'
    IF needrxu | needtools THEN EXIT 1
    RETURN

/****************************************************************/
