- $filename=IkiWiki::linkpage(
- IkiWiki::possibly_foolish_untaint(
- attachment_location($form->field('page')).
- IkiWiki::basename($filename)));
- if (IkiWiki::file_pruned($filename, $config{srcdir})) {
- error(gettext("bad attachment filename"));
- }
-
- # Check that the user is allowed to edit a page with the
- # name of the attachment.
- IkiWiki::check_canedit($filename, $q, $session, 1);
-
- # Use a special pagespec to test that the attachment is valid.
- my $allowed=1;
- foreach my $admin (@{$config{adminuser}}) {
- my $allowed_attachments=IkiWiki::userinfo_get($admin, "allowed_attachments");
- if (defined $allowed_attachments &&
- length $allowed_attachments) {
- $allowed=pagespec_match($filename,
- $allowed_attachments,
- file => $tempfile,
- user => $session->param("name"),
- ip => $ENV{REMOTE_ADDR},
- );
- last if $allowed;
- }
- }
- if (! $allowed) {
- error(gettext("attachment rejected")." ($allowed)");
- }
-
- # Needed for fast_file_copy and for rendering below.
- require IkiWiki::Render;
-
- # Move the attachment into place.
- # Try to use a fast rename; fall back to copying.
- IkiWiki::prep_writefile($filename, $config{srcdir});
- unlink($config{srcdir}."/".$filename);
- if (rename($tempfile, $config{srcdir}."/".$filename)) {
- # The temp file has tight permissions; loosen up.
- chmod(0666 & ~umask, $config{srcdir}."/".$filename);
- }
- else {
- my $fh=$q->upload('attachment');
- if (! defined $fh || ! ref $fh) {
- # needed by old CGI versions
- $fh=$q->param('attachment');
- if (! defined $fh || ! ref $fh) {
- # even that doesn't always work,
- # fall back to opening the tempfile
- $fh=undef;
- open($fh, "<", $tempfile) || error("failed to open \"$tempfile\": $!");
- }
- }
- binmode($fh);
- writefile($filename, $config{srcdir}, undef, 1, sub {
- IkiWiki::fast_file_copy($tempfile, $filename, $fh, @_);
- });
- }