root/branches/release-26/lib/MT/FileMgr/Local.pm @ 1174

Revision 1174, 4.1 kB (checked in by bchoate, 23 months ago)

Updated copyright year for source.

  • Property svn:keywords set to Author Date Id Revision
Line 
1# Movable Type (r) Open Source (C) 2001-2008 Six Apart, Ltd.
2# This program is distributed under the terms of the
3# GNU General Public License, version 2.
4#
5# $Id$
6
7package MT::FileMgr::Local;
8use strict;
9
10use MT::FileMgr;
11@MT::FileMgr::Local::ISA = qw( MT::FileMgr );
12
13use Symbol;
14use Fcntl qw( :DEFAULT :flock );
15
16sub get_data {
17    my $fmgr = shift;
18    my($from, $type) = @_;
19    my($fh);
20    if (!$fmgr->is_handle($from)) {
21        $fh = gensym();
22        open $fh, $from
23            or return $fmgr->error(MT->translate(
24                "Opening local file '[_1]' failed: [_2]", $from, "$!" ));
25    } else {
26        $fh = $from;
27    }
28    if ($type && $type eq 'upload') {
29        binmode($fh);
30    }
31    my($data);
32    { local $/; $data = <$fh>; }
33    close $fh if !$fmgr->is_handle($from);
34    $data;
35}
36
37## $type is either 'upload' or 'output'
38sub put {
39    my $fmgr = shift;
40    my($from, $to, $type) = @_;
41    my $rv;
42    if (!$fmgr->is_handle($from)) {
43        my $fh = gensym();
44        open $fh, $from
45            or return $fmgr->error(MT->translate(
46                "Opening local file '[_1]' failed: [_2]", $from, "$!"));
47        $rv = _write_file($fmgr, $fh, $to, $type);
48        close $fh;
49    } else {
50        $rv = _write_file($fmgr, $from, $to, $type);
51    }
52    $rv;
53}
54
55*put_data = \&_write_file;
56
57sub _write_file {
58    my $fmgr = shift;
59    my($from, $to, $type) = @_;
60    local *FH;
61    my($umask, $perms);
62    my $cfg = MT->config;
63    if ($type && $type eq 'upload') {
64        $umask = $cfg->UploadUmask;
65        $perms = $cfg->UploadPerms;
66    } else {
67        $umask = $cfg->HTMLUmask;
68        $perms = $cfg->HTMLPerms;
69    }
70    my $old = umask(oct $umask);
71    sysopen FH, $to, O_RDWR|O_CREAT|O_TRUNC, oct $perms
72        or return $fmgr->error(MT->translate(
73            "Opening local file '[_1]' failed: [_2]", $to, "$!"));
74    if ($type && $type eq 'upload') {
75        binmode(FH);
76        binmode($from) if $fmgr->is_handle($from);
77    }
78    ## Lock file unless NoLocking specified.
79    flock FH, LOCK_EX unless $cfg->NoLocking;
80    seek FH, 0, 0;
81    truncate FH, 0;
82    my $bytes = 0;
83    if ($fmgr->is_handle($from)) {
84        while (my $len = read $from, my($block), 8192) {
85            print FH $block;
86            $bytes += $len;
87        }
88    } else {
89        print FH $from;
90        $bytes = length($from);
91    }
92    close FH;
93    umask($old);
94    $bytes;
95}
96
97sub exists { -e $_[1] }
98
99sub can_write { -w $_[1] }
100
101sub mkpath {
102    my $fmgr = shift;
103    my($path) = @_;
104    require File::Path;
105    my $umask = oct MT->config->DirUmask;
106    my $old = umask($umask);
107    eval { File::Path::mkpath([$path], 0, 0777) };
108    return $fmgr->error($@) if $@;
109    umask($old);
110    1;
111}
112
113sub rename {
114    my $fmgr = shift;
115    my($from, $to) = @_;
116    rename $from, $to
117       or return $fmgr->error(MT->translate(
118           "Renaming '[_1]' to '[_2]' failed: [_3]", $from, $to, "$!"));
119    1;
120}
121
122sub content_is_updated {
123    my $fmgr = shift;
124    my($file, $content) = @_;
125    return 1 unless -e $file;
126    ## If the system has Digest::MD5, compare MD5 hashes; otherwise
127    ## read in the file and compare the strings.
128    my $fh = gensym();
129    open $fh, $file or return 1;
130    if (eval { require Digest::MD5; 1 }) {
131        my $ctx = Digest::MD5->new;
132        $ctx->addfile($fh);
133        close $fh;
134        my $data;
135        if ($] >= 5.007003) {
136            require Encode;
137            $data = $$content;
138            Encode::_utf8_off($data);
139        } elsif ($] >= 5.006001) {
140            $data = pack 'C0A*', $$content;
141        } else {
142            $data = $$content;
143        }
144        return $ctx->digest ne Digest::MD5::md5($data);
145    } else {
146        my $data;
147        binmode $fh;
148        while (read $fh, my($chunk), 8192) {
149            $data .= $chunk;
150        }
151        close $fh;
152        return $$content ne $data;
153    }
154}
155
156sub delete {
157    my $fmgr = shift;
158    my ($file) = @_;
159
160    return 1 unless -e $file or -l $file;
161    unlink $file
162       or return $fmgr->error(MT->translate(
163           "Deleting '[_1]' failed: [_2]", $file, "$!"));
164    1;
165}
166
1671;
168__END__
169
170=head1 NAME
171
172MT::FileMgr::Local
173
174=head1 AUTHOR & COPYRIGHT
175
176Please see L<MT/AUTHOR & COPYRIGHT>.
177
178=cut
Note: See TracBrowser for help on using the browser.