The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

NAME

File::Save::Home - Place file safely under user home directory

VERSION

This document refers to version 0.02, released November 12, 2005.

SYNOPSIS

    use File::Save::Home qw(
        get_home_directory
        get_subhome_directory_status
        make_subhome_directory
        restore_subhome_directory_status 
        conceal_target_file 
        reveal_target_file 
        make_subhome_temp_directory 
    );

    $home_dir = get_home_directory();

    $desired_dir_ref = get_subhome_directory_status("desired/directory");

    $desired_dir = make_subhome_directory($desired_dir_ref);

    restore_subhome_directory_status($desired_dir_ref);

    $target_ref = conceal_target_file( {
        dir     => $desired_dir,
        file    => 'file_to_be_checked',
        test    => 0,
    } );

    reveal_target_file($target_ref);

    $tmpdir = make_subhome_temp_directory;

DESCRIPTION

In the course of deploying an application on another user's system, you sometimes need to place a file in or underneath that user's home directory. Can you do so safely?

This Perl extension provides several functions which try to determine whether you can, indeed, safely create directories and files underneath a user's home directory. Among other things, if you are placing a file in such a location only temporarily -- say, for testing purposes -- you can temporarily hide any already existing file with the same name and restore it to its original name and timestamps when you are done.

USAGE

get_home_directory()

Analyzes environmental information to determine whether there exists on the system a 'HOME' or 'home-equivalent' directory. Takes no arguments. Returns that directory if it exists; croaks otherwise.

On Win32, this directory is the one returned by the following function from the Win32module:

    Win32->import( qw(CSIDL_LOCAL_APPDATA) );
    $realhome =  Win32::GetFolderPath( CSIDL_LOCAL_APPDATA() );

... which translates to something like C:\Documents and Settings\localuser\Local Settings\Application Data.

On Unix-like systems, things are much simpler. We simply check the value of $ENV{HOME}. We cannot do that on Win32 because $ENV{HOME} is not defined there.

get_subhome_directory_status()

Takes as argument a string holding the name of a directory, either single-level (mydir) or multi-level (path/to/mydir). Determines whether that directory already exists underneath the user's home or home-equivalent directory. Calls get_home_directory() internally, then tacks on the path passed as argument. Returns a reference to a three-element hash whose keys are:

abs

The absolute path of the specified directory.

flag

A Boolean value indicating whether that directory already exists (a true value) or not (undef).

top

The uppermost subdirectory passed as the argument to this function.

make_subhome_directory()

Takes as argument the hash reference returned by get_subhome_directory_status(). Examines the first element in that array -- the directory name -- and creates the directory if it doesn't already exist. The function croaks if the directory cannot be created.

restore_subhome_directory_status()

Undoes make_subhome_directory(), i.e., if there was no specified directory under the user's home directory on the user's system before testing, any such directory created during testing is removed. On the other hand, if there was such a directory present before testing, it is left unchanged.

make_subhome_temp_directory()

Creates a randomly named temporary directory underneath the home or home-equivalent directory returned by get_home_directory(). This is accomplished by use of File::Temp::tempdir (DIR = $home, CLEANUP => 1)>. Returns the directory path if succesful; croaks otherwise.

Note: Any temporary directory so created remains in existence for the duration of the program, but is deleted (along with all its contents) when the program exits.

conceal_target_file()

Determines whether file with specified name already exists in specified directory and, if so, temporarily hides it by renaming it with a .hidden suffix and storing away its last access and modification times. Takes as argument a reference to a hash with these keys:

dir

The directory in which the file is presumed to exist.

file

The targeted file, i.e., the file to be temporarily hidden if it already exists.

test

Boolean value which, if turned on (1), will cause the function, when called, to run two Test::More::ok() tests. Defaults to off (0).

Returns a reference to a hash with these keys:

full

The absolute path to the target file.

hidden

The absolute path to the now-hidden file.

atime

The last access time to the target file ((stat($file{full}))[8]).

modtime

The last modification time to the target file ((stat($file{full}))[9]).

test

The value of the key test in the hash passed by reference as an argument to this function.

reveal_target_file()

Used in conjunction with conceal_target_file() to restore the original status of the file targeted by conceal_target_file(), i.e., renames the hidden file to its original name by removing the .hidden suffix, thereby deleting any other file with the original name created between the calls tothe two functions. croaks if the hidden file cannot be renamed. Takes as argument the hash reference returned by conceal_target_file(). If the value for the test key in the hash passed as an argument to conceal_target_file() was true, then a call to reveal_target_file will run three Test::More::ok() tests.

BUGS AND TODO

So far tested only on Unix-like systems and Win32.

AUTHOR

        James E Keenan
        CPAN ID: JKEENAN
        jkeenan@cpan.org
        http://search.cpan.org/~jkeenan

ACKNOWLEDGMENTS

The subroutines in this module draw upon subroutines in ExtUtils::ModuleMaker::Auxiliary and ExtUtils::ModuleMaker::Utility. After I made a presentation to the Toronto Perlmongers on October 27, 2005, Michael Graham suggested that these functions could be extracted to a separate Perl extention for more general applicability. This module is the implementation of Michael's suggestion.

COPYRIGHT

This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.

The full text of the license can be found in the LICENSE file included with this module.

SEE ALSO

perl(1). ExtUtils::ModuleMaker::Auxiliary. ExtUtils::ModuleMaker::Utility.