############################################################################### # Downloads.pm # # $Date: 01.09.2026 $ # ############################################################################### # YaBB: Yet another Bulletin Board # # Open-Source Community Software for Webmasters # # Version: YaBBForum 3.1 # # Packaged: 01 Sep, 2026 # # Distributed by: https://yabbforum.nz # # =========================================================================== # # Copyright (c) 2000-2026 YaBB (yabbforum.nz) - All Rights Reserved. # # Software by: The YaBB Development Team # # with assistance from the YaBB community. # ############################################################################### use CGI::Carp qw(fatalsToBrowser); our $VERSION = '3.1'; $downloadspmver = 'YaBBForum 3.1'; if ( $action eq 'detailedversion' ) { return 1; } get_template('Downloads'); get_micon(); sub DownloadView { if ( $guest_media_disallowed && $iamguest ) { fatal_error('members_only'); } LoadLanguage('FA'); print_output_header(); $output = $downloads_top; $output =~ s/{yabb fatxt39}/$fatxt{'39'}/sm; my $thread = $INFO{'thread'}; if ( !ref $thread_arrayref{$thread} ) { fopen( MSGTXT, "$datadir/$thread.txt" ) or fatal_error( 'cannot_open', "$datadir/$thread.txt", 1 ); @{ $thread_arrayref{$thread} } = ; fclose(MSGTXT); } my $threadname = ( split /\|/xsm, ${ $thread_arrayref{$thread} }[0], 2 )[0]; my @attachinput = map { split /,/xsm, ( split /\|/xsm, $_ )[12] } @{ $thread_arrayref{$thread} }; chomp @attachinput; my ( %attachinput, $viewattachments ); map { $attachinput{$_} = 1; } @attachinput; fopen( AML, "$vardir/attachments.txt" ) or fatal_error( 'cannot_open', "$vardir/attachments.txt", 1 ); @attachinput = grep { $_ =~ /$thread\|.+\|(.+)\|\d+\s+/xsm && exists $attachinput{$1} } ; fclose(AML); my $max = @attachinput; my $sort = $INFO{'sort'} || ( ( ( $ttsureverse && ${ $uid . $username }{'reversetopic'} ) || $ttsreverse ) ? -1 : 1 ); my $newstart = $INFO{'newstart'} || 0; my $colspan = ( $iamadmin || $iamgmod ) ? 8 : 7; if ( !$max ) { $viewattachments .= $downloads_att; $viewattachments =~ s/{yabb colspan}/$colspan/gsm; $viewattachments =~ s/{yabb colspan}/$colspan/gsm; $viewattachments =~ s/{yabb threadname}/$threadname/gsm; $viewattachments =~ s/{yabb fatxt48}/$fatxt{'38'}/gsm; $viewattachments =~ s/{yabb fatxt70}/$fatxt{'70'}/gsm; $viewattachments =~ s/{yabb fatxt71}/$fatxt{'71'}/gsm; } else { if ( $iamadmin || $iamgmod ) { LoadLanguage('Admin'); $output .= qq~
~; } else { $output .= qq~ ~; } $output .= qq~ ~; my @attachments; if ( $sort > 0 ) { # sort ascending if ( $sort == 1 || $sort == 5 || $sort == 6 || $sort == 8 ) { @attachments = sort { ( split /\|/xsm, $a )[$sort] <=> ( split /\|/xsm, $b )[$sort]; } @attachinput; # sort size, date, count numerically } elsif ( $sort == 100 ) { @attachments = sort { lc( ( split /\./xsm, ( split /\|/xsm, $a )[7] )[1] ) cmp lc( ( split /\./xsm, ( split /\|/xsm, $b )[7] )[1] ); } @attachinput; # sort extension lexically } else { @attachments = sort { lc( ( split /\|/xsm, $a )[$sort] ) cmp lc( ( split /\|/xsm, $b )[$sort] ); } @attachinput; # sort lexically } } else { # sort descending if ( $sort == -1 || $sort == -5 || $sort == -6 || $sort == -8 ) { @attachments = reverse sort { ( split /\|/xsm, $a )[ -$sort ] <=> ( split /\|/xsm, $b )[ -$sort ]; } @attachinput; # sort size, date, count numerically } elsif ( $sort == -100 ) { @attachments = reverse sort { lc( ( split /\./xsm, ( split /\|/xsm, $a )[7] )[1] ) cmp lc( ( split /\./xsm, ( split /\|/xsm, $b )[7] )[1] ); } @attachinput; # sort extension lexically } else { @attachments = reverse sort { lc( ( split /\|/xsm, $a )[ -$sort ] ) cmp lc( ( split /\|/xsm, $b )[ -$sort ] ); } @attachinput; # sort lexically } } $postdisplaynum = 8; $newstart = ( int( $newstart / 25 ) ) * 25; $tmpa = 1; if ( $newstart >= ( ( $postdisplaynum - 1 ) * 25 ) ) { $startpage = $newstart - ( ( $postdisplaynum - 1 ) * 25 ); $tmpa = int( $startpage / 25 ) + 1; } if ( $max >= $newstart + ( $postdisplaynum * 25 ) ) { $endpage = $newstart + ( $postdisplaynum * 25 ); } else { $endpage = $max; } if ( $startpage > 0 ) { $pageindex = qq~1 ... ~; } if ( $startpage == 25 ) { $pageindex = qq~1 ~; } foreach my $counter ( $startpage .. ( $endpage - 1 ) ) { if ( $counter % 25 == 0 ) { $pageindex .= $newstart == $counter ? qq~$tmpa ~ : qq~$tmpa ~; $tmpa++; } } $lastpn = int( $max / 25 ) + 1; $lastptn = ( $lastpn - 1 ) * 25; if ( $endpage < $max - (25) ) { $pageindexadd = q~... ~; } if ( $endpage != $max ) { $pageindexadd .= qq~$lastpn~; } $pageindex .= $pageindexadd; $pageindex = qq~$fatxt{'64'}: $pageindex~; $numbegin = ( $newstart + 1 ); $numend = ( $newstart + 25 ); if ( $numend > $max ) { $numend = $max; } if ( $max == 0 ) { $numshow = q{}; } else { $numshow = qq~($numbegin - $numend)~; } my ( %attach_gif, $ext ); foreach my $row ( splice @attachments, $newstart, 25 ) { chomp $row; my ( $amthreadid, $amreplies, $amthreadsub, $amposter, $amcurrentboard, $amkb, $amdate, $amfn, $amcount ) = split /\|/xsm, $row; if ( $amfn =~ /\.(.+?)$/xsm ) { $ext = $1; } if ( !exists $attach_gif{$ext} ) { $attach_gif{$ext} = ( $ext && -e "$htmldir/Templates/Forum/$useimages/$att_img{$ext}" ) ? "$imagesdir/$att_img{$ext}" : "$micon_bg{'paperclip'}"; } $amdate = timeformat($amdate); if ( length($amthreadsub) > 20 ) { $amthreadsub = substr( $amthreadsub, 0, 20 ) . q{...}; } if ( $iamadmin || $iamgmod ) { $att_admin = $my_att_admin; } else { $att_admin = q{}; } $viewattachments .= $downloads_att_b; $viewattachments =~ s/{yabb att_admin}/$att_admin/gsm; $viewattachments =~ s/{yabb amfn}/$amfn/gsm; $viewattachments =~ s/{yabb attach_gif}/$attach_gif{$ext}/gsm; $viewattachments =~ s/{yabb thread}/$thread/gsm; $viewattachments =~ s/{yabb amkb}/$amkb/gsm; $viewattachments =~ s/{yabb amdate}/$amdate/gsm; $viewattachments =~ s/{yabb amcount}/$amcount/gsm; $viewattachments =~ s/{yabb amreplies}/$amreplies/gsm; $viewattachments =~ s/{yabb amthreadsub}/$amthreadsub/gsm; $viewattachments =~ s/{yabb amposter}/$amposter/gsm; } if ( $iamadmin || $iamgmod ) { $att_admin_b = $my_att_admin_b; $att_admin_c = $my_att_admin_c; } else { $att_admin_b = q{}; $att_admin_c = ' '; } $viewattachments .= $downloads_att_c; $viewattachments =~ s/{yabb att_admin_b}/$att_admin_b/gsm; $viewattachments =~ s/{yabb att_admin_c}/$att_admin_c/gsm; $viewattachments =~ s/{yabb amv_txt38a}/$amv_txt{'38a'}/gsm; $viewattachments =~ s/{yabb admin_txt32}/$admin_txt{'32'}/gsm; $viewattachments =~ s/{yabb thread}/$thread/gsm; $viewattachments =~ s/{yabb threadname}/$threadname/gsm; $viewattachments =~ s/{yabb fatxt70}/$fatxt{'70'}/gsm; $viewattachments =~ s/{yabb fatxt71}/$fatxt{'71'}/gsm; $viewattachments =~ s/{yabb pageindex}/$pageindex/gsm; $output .= qq~ ~; } my $class_sortattach = $sort =~ /7/sm ? 'windowbg2' : 'windowbg'; my $class_sorttype = $sort =~ /100/sm ? 'windowbg2' : 'windowbg'; my $class_sortsize = $sort =~ /5/sm ? 'windowbg2' : 'windowbg'; my $class_sortdate = $sort =~ /6/sm ? 'windowbg2' : 'windowbg'; my $class_sorcount = $sort =~ /8/sm ? 'windowbg2' : 'windowbg'; my $class_sortsubj = $sort =~ /1$/sm ? 'windowbg2' : 'windowbg'; my $class_sortuser = $sort =~ /3/sm ? 'windowbg2' : 'windowbg'; if ( $iamadmin || $iamgmod ) { $att_out_admin_a = $my_out_att_admin_a; } else { $att_out_admin_a = q{}; } $output .= $downloads_att_out_a; $output =~ s/{yabb colspan}/$colspan/gsm; $output =~ s/{yabb threadname}/$threadname/gsm; $output =~ s/{yabb pageindex}/$pageindex/gsm; $output =~ s/{yabb max}/$max/gsm; $output =~ s/{yabb numshow}/$numshow/gsm; $output =~ s/{yabb fatxt39}/$fatxt{'39'}/gsm; $output =~ s/{yabb fatxt76}/$fatxt{'76'}/gsm; $output =~ s/{yabb fatxt75}/$fatxt{'75'}/gsm; $output =~ s/{yabb fatxt28}/$fatxt{'28'}/gsm; $output .= $att_out_admin_a; $output =~ s/{yabb fatxt45}/$fatxt{'45'}/gsm; my $att_text; $rsort = ( $sort == 7 ? -7 : 7 ); $att_text = $my_att_sort; $att_text =~ s/{yabb attsort}/$rsort/gsm; $att_text =~ s/{yabb attclass}/$class_sortattach/gsm; $att_text =~ s/{yabb atttext}/$fatxt{'40'}/gsm; $output .= $att_text; $rsort = ( $sort == 100 ? -100 : 100 ); $att_text = $my_att_sort; $att_text =~ s/{yabb attsort}/$rsort/gsm; $att_text =~ s/{yabb attclass}/$class_sorttype/gsm; $att_text =~ s/{yabb atttext}/$fatxt{'40a'}/gsm; $output .= $att_text; $rsort = ( $sort == 5 ? -5 : 5 ); $att_text = $my_att_sort; $att_text =~ s/{yabb attsort}/$rsort/gsm; $att_text =~ s/{yabb attclass}/$class_sortsize/gsm; $att_text =~ s/{yabb atttext}/$fatxt{'41'}/gsm; $output .= $att_text; $rsort = ( $sort == -6 ? 6 : -6 ); $att_text = $my_att_sort; $att_text =~ s/{yabb attsort}/$rsort/gsm; $att_text =~ s/{yabb attclass}/$class_sortdate/gsm; $att_text =~ s/{yabb atttext}/$fatxt{'43'}/gsm; $output .= $att_text; $rsort = ( $sort == -8 ? 8 : -8 ); $att_text = $my_att_sort; $att_text =~ s/{yabb attsort}/$rsort/gsm; $att_text =~ s/{yabb attclass}/$class_sorcount/gsm; $att_text =~ s/{yabb atttext}/$fatxt{'41a'}/gsm; $output .= $att_text; $rsort = ( $sort == 1 ? -1 : 1 ); $att_text = $my_att_sort; $att_text =~ s/{yabb attsort}/$rsort/gsm; $att_text =~ s/{yabb attclass}/$class_sortsubj/gsm; $att_text =~ s/{yabb atttext}/$fatxt{'44'}/gsm; $output .= $att_text; $rsort = ( $sort == 3 ? -3 : 3 ); $att_text = $my_att_sort; $att_text =~ s/{yabb attsort}/$rsort/gsm; $att_text =~ s/{yabb attclass}/$class_sortuser/gsm; $att_text =~ s/{yabb atttext}/$fatxt{'42'}/gsm; $output .= $att_text; $output .= $downloads_tbl_end; $output =~ s/{yabb thread}/$thread/gsm; $output =~ s/{yabb viewattachments}/$viewattachments/gsm; if ( $max && ( $iamadmin || $iamgmod ) ) { $output .= '
'; } $output .= $downloads_bottom; print_HTML_output_and_finish(); return; } sub DownloadFileCouter { $dfile = $INFO{'file'}; if ( $guest_media_disallowed && $iamguest ) { fatal_error( q{}, $maintxt{'40'} ); } if ( !-e "$uploaddir/$dfile" ) { fatal_error( q{}, "$maintxt{'23'} $dfile$maintxt{'23a'}" ); } fopen( ATM, "<$vardir/attachments.txt", 1 ) or fatal_error( 'cannot_open', "$vardir/attachments.txt", 1 ); my @attachments = ; fclose( ATM ); for my $i ( 0 .. $#attachments ) { $attachments[$i] =~ s/(.+\|)(.+)\|(\d+)(\s+)$/ $1 . ($dfile eq $2 ? "$2|" . ($3 + 1) : "$2|$3") . $4 /exsm; } fopen( ATM, ">$vardir/attachments.txt", 1 ) or fatal_error( 'cannot_open', "$vardir/attachments.txt", 1 ); print {ATM} @attachments or croak "$croak{'print'} ATM"; fclose(ATM); print "Location: $uploadurl/$dfile\n\r\n\r" or croak "$croak{'print'} Location"; exit; } 1;