summaryrefslogtreecommitdiff
path: root/plex.pls
blob: 4c5ab472a1e99ef9e3e51675372ca021a1f3ceaa (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
#!/usr/bin/perl -w
#
# iceplex
#
# Copyright (c) 2003 Ivan Kohler
# All rights reserved.
# This program is free software; you can redistribute it and/or modify it under
# the same terms as Perl itself.

use strict;
use subs qw(suidsetup pick_server);
use CGI;
use CGI::Carp qw(fatalsToBrowser);
use Digest::MD5 qw(md5_hex);
use DBI;
use Net::SSH qw(ssh);

suidsetup();

# pull in configuration
use vars qw($dsn $user $pass $mp3path $port);
use vars qw($override_query $fileno_query);
use vars qw(%extension2type);
require "/etc/iceplex.conf";

#detect .pls or .m3u filetype
$0 =~ /\.(pls|m3u)$/i or die "must be named with .pls or .m3u extension";
my $extension = lc($1);

#connect to database
my $dbh = DBI->connect($dsn, $user, $pass) or die $DBI::errstr;

#pick a server
my $server = pick_server();

#get customer & user from client browser
my $cgi = new CGI;
$cgi->param('customer') =~ /^(\d{1,10})$/ or die 'illegal customer numer';
my $customer = sprintf("%6d", $1); #!! how many digits in customer #?
$cgi->param('user') =~ /^(\d{1,10})$/ or die 'illegal user numer';
my $user = sprintf("%4d", $1); #!! how many digits in user #?

#get file number
my $fileno = '';
if ( $override_query ) {
  my $sth = $dbh->prepare( $override_query ) or die $dbh->errstr;
  $sth->execute($customer, $user) or die $sth->errstr;
  my $row = $sth->fetchrow_arrayref;
  $fileno = $row->[0] if $row;
}
if ( !length($fileno) && $fileno_query ) {
  my $sth = $dbh->prepare( $fileno_query ) or die $dbh->errstr;
  $sth->execute($customer, $user) or die $sth->errstr;
  my $row = $sth->fetchrow_arrayref;
  die "No files for user $user of customer $customer" unless $row;
  $fileno = $row->[0];
}
$fileno = '000' unless length($fileno); #default

#genarate filename
my $filename = "$mp3path/$customer-$user-$fileno.mp3";

#disconnect from database
$dbh->disconnect;

#generate a mountpoint
md5_hex($cgi->remote_host. $$. time. int(rand(4294967296))) =~ /^(\w+)$/;
my $mountpoint = $1;

#signal encoder to start streaming to mountpoint & wait for confirmation
warn "ssh $server yashout $filename $mountpoint $port\n";
ssh($server, 'yashout', $filename, $mountpoint, $port );

#send file back to client browser

print $cgi->header( -type => $extension2type{$extension} );
print "[playlist]\nNumberOfEntries=1\nFile1=" if $extension eq 'pls';
print "http://$server:$port/$mountpoint\n";

###
# subroutiens
###

sub suidsetup {
  $ENV{'PATH'} ='/usr/local/bin:/usr/bin:/usr/ucb:/bin';
  $ENV{'SHELL'} = '/bin/sh';
  $ENV{'IFS'} = " \t\n";
  $ENV{'CDPATH'} = '';
  $ENV{'ENV'} = '';
  $ENV{'BASH_ENV'} = '';

  $< = $>; #correct uid for spawned ssh process
}

sub pick_server {
  my $sth = $dbh->prepare(
    "SELECT servername FROM iceplex_servers ".
    "WHERE status = 'online' ".
    "ORDER BY listeners ASC LIMIT 1"
  ) or die $dbh->errstr;
  $sth->execute() or die $sth->errstr;
  my $row = $sth->fetchrow_arrayref;
  die "No servers online!" unless $row;
  $row->[0];
}