Getvar

NAME
    Getvar: Get environment variable

VERSION
    9; 23Feb2004

AUTHOR
    Bill Stewart (bstewart@iname.com)

SYNOPSIS
    getvar -v var -f file [-p prompt] [-l length] [-t timeout]
           [-b] [-m] [-n] [-o] [-u]

AVAILABILITY
    DOS version (getvard.exe)
    Win32 console mode version (getvar.exe)

    Getvard.exe is a real-mode MS-DOS version that should work with any
    version of DOS, Windows 9x, etc. Getvar.exe is a Win32 console-mode
    version for Windows 9x/NT/2000 (Intel only).

    You can use the DOS version in NT/2000 also, but since it runs in a DOS
    emulator, it runs much more slowly (the screen isn't updated as quickly
    or smoothly).

    Due to the fact that Win32 console programs are very flaky on the
    Windows 9x platform (Windows 95/98/Me), it's better to use the DOS
    version there.

    Note that CMD.EXE on Windows 2000 and later supports a variation of the
    SET command (SET /P) that allows interactive user input for a batch
    file. While this approach is "cleaner" than getvar's approach (no
    temporary files are used), it only works for CMD.EXE in Windows 2000
    and later. Also, Windows 2000's SET /P command doesn't allow you to
    modify a pre-existing variable; it can only overwrite an existing
    variable or create a new one. Getvar does not have this limitation.

DESCRIPTION
    Getvar is a utility intended for use in batch files (scripts). It's
    purpose is to allow interactive editing of an environment variable.
    This allows a batch file to interact with a user using environment
    variables. This has other uses as well; e.g. a simple script can be
    constructed to allow editing of the system path.

    Getvar works by allowing the user to edit a string interactively. When
    Enter is pressed, it creates a file containing a SET command, the
    environment variable name, an equals sign, and the value of the string
    edited. The created file is a temporary batch file that the first batch
    file can call to set the variable.

    The following keystrokes can be used to interactively edit the contents
    of the variable:

        Key         Function
        ---------------------------------------------------------
        Home        Beginning of input line
        End         End of input line
        Left        Left one character
        Right       Right one character
        Ctrl+Left   Left one word
        Ctrl+Right  Right one word
        Ctrl+Home   Delete to beginning of input line
        Ctrl+End    Delete to end of input line
        Esc         Delete entire input line
        Ctrl+C      Aborts input
        Ctrl+U      "Undo" (restores original line contents)
        Ctrl+Z      (Same as Ctrl+U)
        Ins         Toggle between insert mode and overtype mode

    Notes on the line editor:

    * There is no visual indication of insert vs. overtype mode.
    * The default is to place the cursor at the end of the input line
      rather than the beginning (this can be reversed by specifying -b,
      below).
    * The line editor defaults to insert mode, unless the -o parameter is
      specified (see below).
    * By default, after pressing Ctrl+U or Ctrl+Z, the cursor is
      repositioned at the end of the string, unless the -b switch is used.

PARAMETERS
    Command-line parameters that start with a forward slash (/) or a hyphen
    (-) character are "switches" that modify the program's behavior, and
    may be specified in upper or lowercase. Switches that don't require an
    additional argument may be combined (e.g. -a -b is the same as -ab).

    If a command-line parameter's argument needs to contain one or more
    spaces or tabs, the argument needs to be enclosed in either single (')
    or double (") quotation marks. The general rule is that if a
    parameter's argument needs embedded spaces, separate the parameter and
    it's argument with a space and enclose the argument in quotes.

    -h  Displays an on-screen synopsis.

    -v  Specifies the name of the environment variable to present to the
        user for interactive editing. This switch is required. If the
        variable is not defined, the input line is blank, allowing a new
        variable to be defined. The environment variable name cannot
        contain spaces or the characters <, >, or |.

    -f  Specifies the output file that will be created with the needed
        "set" command. If the file already exists, it will be overwritten.
        The output filename should have a .bat suffix (.cmd can also be
        used with CMD.EXE) so that the file can simply be "called" to set
        the variable. This switch is required.

    -p  Specifies a prompt that should be displayed just before displaying
        the environment variable for interactive editing. If the prompt
        should contain one or more spaces or tabs, enclose it in quotation
        marks.

    -l  Limits the length of the string that can be edited. If the variable
        is longer than the specified length, it is truncated. If you do not
        specify -l, the maximum length is used. The maximum length depends
        on the operating system and the length of the environment variable
        name (see notes below).

    -t  Specifies a timeout period, in seconds. If nothing is typed within
        the specified number of seconds, getvar will behave as if the Enter
        key was pressed on the keyboard.

    -b  Indicates that the cursor should start out at the beginning of the
        input line instead of the end.

    -m  Specifies masked input. As characters are typed, only an asterisk
        character appears on the screen. This option does not permit any
        pre-existing variable value to be edited; if the variable already
        exists and -m is specified, the input line will be blank. Cannot be
        used with -n; -m takes precedence if both are specified.

    -n  Only allows numeric entry (digits 0-9). If the initial contents of
        the variable contains any non-numeric characters, it is emptied and
        nothing is presented for editing (as if the variable was blank).
        Cannot be used with -m; -m takes precedence if both are specified.

    -o  Indicates that the line editor should start in overtype mode rather
        than insert mode.

    -u  Forces entered characters to upper case. If the initial contents of
        the variable contains any lower case characters, they are changed
        to upper case.

    The string "--" (without the quotes) indicates the end of switches on
    the command line. This is useful if the prompt contains a string that
    might be confused with a switch.

EXIT STATUS
    The following exit codes are used:

    0   Successful completion: Enter was pressed at the input prompt and
        the output file containing the SET command was successfully
        created.

    1   Ctrl+C was pressed at the input prompt to abort the input; output
        file was not created.

    2   Input line was empty; output file was not created.

    3   Error in one or more command-line parameters (required parameter
        missing, invalid output file name, could not create the file,
        etc.).

    A batch file can use an "IF ERRORLEVEL" command to check getvar's exit
    code.

EXAMPLES
    1.  getvar -v _NAME -f TMP.BAT -p "Enter your name: "

        Displays the following prompt on the screen, and waits for a typed
        response:

        Enter your name:

        If you type "Bill Gates" (without the quotes) and press Enter,
        getvar creates a file tmp.bat which contains the following line:

        set _NAME=Bill Gates

        If you then call TMP.BAT, it will have the effect of defining the
        environment variable.

        Your batch file is responsible for making sure an existing variable
        called _NAME doesn't get overwritten and for deleting TMP.BAT.

    2.  The following lines are in a batch file. They are numbered for
        reference:

            [...other batch file lines here...]
        1.  set _YN=N
        2.  getvar -v _YN -f %TEMP%\$0$.BAT -l 1 -b -o -u -p "Sure (Y/N)? "
        3.  if errorlevel 1 goto :END
        4.  call %TEMP%\$0$.BAT
        5.  del %TEMP%\$0$.BAT > NUL
        6.  if not "%_YN%" == "Y" goto :END
            [...do stuff if answer is Y...]
            [...other batch file lines here...]
        7.  :END
        8.  set _YN=

        This batch file fragment defines the variable _YN with an initial
        value of N (line 1), and displays the following prompt:

        Sure (Y/N)? N

        Since the _YN variable is already defined, getvar presents it as
        the initial value at the input prompt (line 2). The length of the
        input is limited to 1 character, and is forced to be in upper case.
        In addition, overtype mode is enabled and the cursor is positioned
        at the beginning of the line (or in this case, on the only
        character in the line).

        If getvar returns an exit code of 1 or higher, line 3 tells the
        batch file to skip to the :END label (line 7).

        Line 4 calls the temporary batch file that defines the environment
        variable, and line 5 deletes the temporary batch file. Line 6 will
        skip down to line 7 (:END) if _YN is anything but Y.

        The last line in the example (line 8) removes the _YN variable from
        the environment.

    3.  This example uses password-style input:

        1.  :GETPW
        2.  getvar -v _PW -f %TEMP%\$0$.BAT -l 14 -m -p "Password: "
        3.  if errorlevel 2 goto :GETPW
        4.  if errorlevel 1 goto :END
        5.  call %TEMP%\$0$.BAT
        6.  del %TEMP%\$0$.BAT > NUL
        7.  if "%PW%"=="whatever" goto :RUNPROG
        8.  echo Incorrect password.
        9.  goto :END
        10. :RUNPROG
        11. [...run some program here...]
        12. :END

        This allows a user to enter up to a 14-character "password." Note
        that this is not in any way secure since the password is stored in
        plain text in the main and temporary batch files. Still, it could
        be useful in low-security environments as a rudimentary form of
        password protection, such as in a DOS-based menu system.

    4.  This example uses the timeout feature:

        1.  @echo off
        2.  set _NAME=
        3.  getvar -v _NAME -f %TEMP%\$0$.BAT -t 10 -p "Enter your name: "
        4.  if errorlevel 1 goto :BYE
        5.  call %TEMP%\$0$.BAT
        6.  del %TEMP%\$0$.BAT > NUL
        7.  echo Your name is %_NAME%
        8.  set _NAME=
        9.  :BYE

        In this example, the _NAME variable is emptied on line 2, so the
        input line will be initially blank. If nothing is typed within 10
        seconds, getvar will return with an exit code of 2 (nothing typed
        on the input line), and it won't create the output file.

        If you initialize the _NAME variable with some value, and nothing
        is typed within 10 seconds, getvar will behave as if you pressed
        Enter, but since the input line was not blank, it will create the
        output file and return an exit code of 0.

    See TESTVAR.BAT, EDITPATH.BAT, and EDITVAR.BAT for more examples on how
    to use getvar.

NOTES--GENERAL
    Getvar provides a flexible extension to batch files, but your batch
    file is responsible for cleaning up after itself; e.g. you must delete
    any temporary batch files you create. Also, be sure to remove unneeded
    variables from the environment. With CMD.EXE, the easiest way to clean
    up unneeded environment variables is to use the setlocal and endlocal
    commands in the script.

    The calling batch file should generally use unique environment variable
    names to avoid unnecessarily changing a variable when the batch file
    exits, unless this is the desired effect. With CMD.EXE, this is easily
    accomplished by using the setlocal and endlocal commands.

    THE FILE SPECIFIED AFTER THE -f SWITCH WILL BE OVERWRITTEN IF IT
    ALREADY EXISTS. Your batch file is responsible for providing a unique
    filename. It is a good practice to use the TEMP variable when
    specifying this filename, indicating that the temporary batch file
    should be placed in a valid temporary directory (e.g. -f
    %temp%\temp1.bat). Make sure that you enclose the entire filename in
    quotes if any part of the entire path might contain spaces (e.g. -f
    "%temp%\tempfilename.bat").

    Of course, you must have read and write access to the directory in
    which you are creating the temporary file (and delete access as well,
    if the batch file is to behave itself and delete temporary files it
    creates).

    The DOS version of getvar (getvard.exe) treats the Ctrl+Break keystroke
    the same as Ctrl+C; the Win32 version (getvar.exe) ignores Ctrl+Break
    altogether. This is a side effect of how the keyboard is handled in the
    different environments.

    In DOS or Windows 9x, the COMMAND.COM program limits batch file lines
    to 1023 characters, and CMD.EXE in Windows NT 4.0 limits batch file
    lines to 2046 characters. To account for these limits, getvar limits
    the maximum length of the contents of the edited environment variable
    accordingly. The formula is as follows:

    DOS/Windows 9x/Windows Me: 1023 - (length of variable name + 5)
    Windows NT 4.0 and later: 2046 - (length of variable name + 5)

    The extra 5 characters are for the word 'SET', the space between 'SET'
    and the environment variable name, and the equals sign.

    For example, with the PATH environment variable, the maximum length of
    the contents of the variable would be as follows:

    DOS/Windows 9x/Windows Me: 1023 - (4 + 5) = 1014
    Windows NT 4.0 and later: 2046 - (4 + 5) = 2037

    If you attempt to specify a length greater than this limit, getvar will
    display an error message and return with an exit code of 3.

    If you enter a string that contains one or more % characters, note that
    they will be doubled when written to the output batch file. If your
    string is at the maximum length limit, it will be truncated to
    accommodate the doubled % character(s).

    For example, suppose you use the command:

        getvar -v V -f V.BAT

    Then you enter the string "15%" (without the quotes). V.BAT will then
    contain:

        SET V=15%%

    When you execute V.BAT, the extra % character causes the shell to
    interpret the following % character literally; then the variable V will
    contain the literal string "15%".

NOTES--DOS VERSION
    The edited environment variable value cannot contain the I/O
    redirection characters <, >, or |. If you enter any of these characters
    on the input line, getvar will display an error message.

NOTES--WIN32 VERSION ON THE NON-NT WINDOWS PLATFORM
    The Win32 version running on the non-NT Windows platform (e.g. Windows
    95, 98, or Me) has the same limits with the <, >, and | I/O redirection
    characters as the DOS version noted above.

NOTES--WIN32 VERSION ON THE WINDOWS NT PLATFORM
    In the Win32 version running on the Windows NT platform (e.g. Windows
    NT and later versions such as Windows 2000, etc.), the following
    characters will be "escaped" with three ^ characters in the output
    batch file: &, (, ), ^, <, >, and |. These characters require special
    treatment due to their special meanings in the shell. Three ^
    characters are necessary to "escape" both the first ^ and the
    subsequent character. If you are up against the maximum length limit
    and your string contains one or more characters that need to be
    escaped, be aware that the string will be truncated to account for the
    extra ^ characters that will be inserted. If you use a command shell
    other than CMD.EXE, this may not work as expected if the shell uses a
    character other than ^ to "escape" the next character.

    When you edit a variable that contains escaped characters (e.g.
    characters prefixed by a ^ symbol), the ^ escape characters are removed
    before displaying the variable's value on the input line.

    For example, suppose you use the command:

        getvar -v V -f V.BAT

    You then enter the string "<Esc>" (without the quotes). The file V.BAT
    will contain the following line:

        SET V=^^^<Esc^^^>

    When you execute V.BAT, the first ^ characters are "escaped", and the
    command is executed as

        SET V=^<Esc^>

    You may then use the variable in subsequent commands without the shell
    attempting to incorrectly interpret the special characters. If you
    subsequently decide to edit the variable with another call to getvar,
    it knows about the ^ characters and removes them before presenting the
    string for editing.

VERSION HISTORY
    Versions are numbered consecutively.

    9   23Feb2004

        Added the timeout feature.

        Fixed a minor command line-parsing bug present in the DOS version.

        Maximum line length is now calculated dynamically depending on the
        OS platform and the length of the environment variable name.

        Fixed a minor bug in the line editor.

        The Win32 version is compiled with Free Pascal 1.0.10.

        Version information in Win32 executable now contains the correct
        language information.

    8   10Jan2003

        Running the executable without arguments displays the help screen
        instead of an error message.

        Checks for illegal characters in environment variable names.

        Rewrote internal handling of special characters: Several instances
        of unnecessary processing were removed.

        Control characters are no longer stripped before editing.

        File I/O improved: The output file is created last (previous
        versions would delete the file if encountering an error; this
        version checks for all other errors first before attempting to
        create the output file).

        The Win32 version is compiled with Free Pascal 1.0.6.

        Both executables are compressed with UPX 1.24.

    7   28Jan2002

        I/O redirection and shell "escape" characters are now handled
        gracefully. In the DOS version or in the Win32 version running on
        the Win9x platform, you cannot enter the following characters as
        part of a string: <, >, or |. The Win32 version running on Windows
        NT or later automatically "escapes" the following characters: &, (,
        ), ^, <, >, and |.

        % characters in an input string are now handled correctly; they are
        doubled in the output batch file.

        If you edit a variable that contains control characters, they will
        be stripped before editing.

        Getvar now uses the Win32 CharToOEMBuff API function to read an
        environment variable for editing. This results in a correct
        character code mapping for multinational characters and currency
        symbols. Other high-bit characters may not be translated correctly.

    6   3Jul2001

        The Win32 version is compiled with Free Pascal 1.0.4 and now
        contains embedded version information and an icon. Both versions
        (DOS and Win32) are compressed with UPX 1.20.

    5   17Jan2001

        Extended maximum line length from 255 to 2040 characters.

        Added overtype mode. Overtype mode can be set as the default by
        specifying -o.

        Can now specify that the line editor start at the beginning of the
        line rather than the end by specifying -b.

    4   13Dec2000

        Recompiled the Win32 version with version 1.0.2 of Free Pascal,
        which fixed a minor bug.

    3   20Nov2000

        Getvar now empties the keyboard buffer before retrieving any
        keystrokes.

    2   06Nov2000

        Changed -p to -m, and the -p parameter is now required before the
        prompt string. The change was made because the "%0\..\" batch file
        syntax in Windows 2000 (see Microsoft Knowledge Base article
        Q121387 for details) places quotes around the %0. The program then
        assumed that this was the prompt and ignored the later prompt on
        the command line. By requiring a -p to prefix the prompt, the
        program parses the command line correctly.

    1   04Oct2000

        Initial release.

TECHNICAL INFORMATION
    Getvar was written in Pascal. The DOS version is compiled with Turbo
    Pascal 7.0, and the Win32 version is compiled with Free Pascal (FPC).
    FPC is a free, Turbo Pascal/Delphi-compatible multi-platform 32-bit
    Pascal compiler that can compile executables for several platforms.
    Visit http://www.freepascal.org/ for more information.
