1808 lines
58 KiB
Perl
1808 lines
58 KiB
Perl
#!/usr/bin/perl
|
|
#
|
|
# @APPLE_LICENSE_HEADER_START@
|
|
#
|
|
#
|
|
# Copyright (c) 1999-2008 Apple Inc. All Rights Reserved.
|
|
#
|
|
# This file contains Original Code and/or Modifications of Original Code
|
|
# as defined in and that are subject to the Apple Public Source License
|
|
# Version 2.0 (the 'License'). You may not use this file except in
|
|
# compliance with the License. Please obtain a copy of the License at
|
|
# http://www.opensource.apple.com/apsl/ and read it before using this
|
|
# file.
|
|
#
|
|
# The Original Code and all software distributed under the License are
|
|
# distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
|
|
# EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
|
|
# INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
|
|
# FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
|
|
# Please see the License for the specific language governing rights and
|
|
# limitations under the License.
|
|
#
|
|
# @APPLE_LICENSE_HEADER_END@
|
|
#
|
|
|
|
require('tag_vals.pl');
|
|
require('tag_types.pl');
|
|
require('tag_formats.pl');
|
|
require('adminprotocol-lib.pl');
|
|
require('cgi-lib.pl');
|
|
require('playlist-lib.pl');
|
|
require('relayxmlparser.pl');
|
|
require('password-utils.pl');
|
|
|
|
# Get the server name, QTSS IP address, and Port from ENV hash
|
|
$servername = $ENV{"SERVER_SOFTWARE"};
|
|
$qtssip = $ENV{"QTSSADMINSERVER_QTSSIP"};
|
|
$qtssport = $ENV{"QTSSADMINSERVER_QTSSPORT"};
|
|
$remoteip = $ENV{"REMOTE_HOST"};
|
|
$accessdir = $ENV{"LANGDIR"};
|
|
$nonAuthenticatedActions = ("|login|logout|AssistSetPassword|");
|
|
$displayedLoginMessage = 0;
|
|
|
|
$auth = '';
|
|
$authheader = '';
|
|
$messageHash = &adminprotolib::GetMessageHash();
|
|
$cookie = '';
|
|
$password = '';
|
|
$iteration = '';
|
|
$cookieExpireSecs = $ENV{"COOKIE_EXPIRE_SECONDS"};
|
|
|
|
# this array will get filled by the foundTag function
|
|
my %endTags = ();
|
|
|
|
# tag depth variable
|
|
my $tag_depth = 0;
|
|
|
|
sub encodeBase64 {
|
|
my $res = '';
|
|
|
|
pos($_[0]) = 0; # ensure start at the beginning
|
|
while ($_[0] =~ /(.{1,45})/gs) {
|
|
$res .= substr(pack('u', $1), 1);
|
|
chop($res);
|
|
}
|
|
$res =~ tr|` -_|AA-Za-z0-9+/|; # `# help emacs
|
|
# fix padding at the end
|
|
my $padding = (3 - length($_[0]) % 3) % 3;
|
|
$res =~ s/.{$padding}$/'=' x $padding/e if $padding;
|
|
return $res;
|
|
}
|
|
|
|
# b64decode(string)
|
|
# Converts a string from base64 format to normal
|
|
sub b64decode {
|
|
local($str) = $_[0];
|
|
local($res);
|
|
$str =~ tr|A-Za-z0-9+=/||cd;
|
|
$str =~ s/=+$//;
|
|
$str =~ tr|A-Za-z0-9+/| -_|;
|
|
while ($str =~ /(.{1,60})/gs) {
|
|
my $len = chr(32 + length($1)*3/4);
|
|
$res .= unpack("u", $len . $1 );
|
|
}
|
|
return $res;
|
|
}
|
|
|
|
sub repeaterExists {
|
|
my $testRepeater = $_[0];
|
|
my $i = 0;
|
|
my $foundItem = '';
|
|
my $currentItem = '';
|
|
|
|
foreach $theItem (@returnedKeys) {
|
|
if ($theItem eq $testRepeater) {
|
|
$foundItem = 1;
|
|
last;
|
|
}
|
|
}
|
|
return $foundItem;
|
|
}
|
|
|
|
sub addIterationAttribute {
|
|
my $tagAttributes = $_[0];
|
|
my $endTagSlash = $_[1];
|
|
my $singleTagSlash = $_[2];
|
|
my $iterationNumber = $_[3];
|
|
if ($endTagSlash eq '/') {
|
|
return '</qtssobject>';
|
|
}
|
|
else {
|
|
return '<qtssobject' . $tagAttributes . " iteration=$iterationNumber" . $singleTagSlash . '>';
|
|
}
|
|
}
|
|
|
|
# this routine, erm, expands repeater tags. Adds an iteration attribute to all contained qtssobject tags.
|
|
sub expandRepeater {
|
|
my $tagAttributes = $_[0];
|
|
my $tagContents = $_[1];
|
|
my $name = '';
|
|
my $arraySize = 0;
|
|
my $currentIteration = 0;
|
|
my $returnedText = '';
|
|
$_ = $tagAttributes;
|
|
if (/ name="[^"]*"| name=[^ (\/>)]*/si) {
|
|
$name = $&;
|
|
$name =~ s/ *name="*//;
|
|
$name =~ s/"//;
|
|
}
|
|
$arraySize = getRepeaterArray($name);
|
|
# return '@' . $returnedKeys[0];
|
|
# $arraySize = scalar(eval('@' . $returnedKeys[0]));
|
|
for ($currentIteration = 0; $currentIteration < $arraySize; $currentIteration++) {
|
|
$_ = $tagContents;
|
|
s{ < ( /*? ) qtssobject ( .*? ) (/*?) >}
|
|
{ addIterationAttribute($2, $1, $3, $currentIteration) }isgxe;
|
|
$returnedText .= $_;
|
|
}
|
|
return $returnedText;
|
|
}
|
|
|
|
# this routine takes the contents of a qtssobject tag and deals with it accordingly
|
|
sub foundTag {
|
|
my $data = '';
|
|
my $tagAttributes = $_[0];
|
|
my $endTagSlash = $_[1];
|
|
my $singleTagSlash = $_[2];
|
|
my $name = '';
|
|
my $type = '';
|
|
my $value = '';
|
|
my $format = '';
|
|
my $userParam = '';
|
|
my $final_value = '';
|
|
$iteration = '';
|
|
$_ = $tagAttributes;
|
|
if ($endTagSlash eq "/") {
|
|
$final_value = $endTags{$tag_depth};
|
|
$tag_depth--;
|
|
return $final_value;
|
|
}
|
|
if (/ name="[^"]*"| name=[^ (\/>)]*/si) {
|
|
$name = $&;
|
|
$name =~ s/ *name="*//;
|
|
$name =~ s/"//;
|
|
}
|
|
if (/ type="[^"]*"| type=[^ (\/>)]*/si) {
|
|
$type = $&;
|
|
$type =~ s/ *type="*//;
|
|
$type =~ s/"//;
|
|
}
|
|
else {
|
|
$type = $defaultTypes{$name};
|
|
}
|
|
if (/ iteration="[^"]*"| iteration=[^ (\/>)]*/si) {
|
|
$iteration = $&;
|
|
$iteration =~ s/ *iteration="*//;
|
|
$iteration =~ s/"//;
|
|
}
|
|
# get the end tag, if necessary
|
|
if ($singleTagSlash eq '') {
|
|
$tag_depth++;
|
|
$endTags{$tag_depth} = $endTagTypes{$type};
|
|
}
|
|
if (/ format="[^"]*"| format=[^ (\/>)]*/si) {
|
|
$format = $&;
|
|
$format =~ s/ *format="*//;
|
|
$format =~ s/"//;
|
|
}
|
|
else {
|
|
$format = $defaultFormats{$name};
|
|
}
|
|
if (/ param="[^"]*"| param=[^ (\/>)]*/si) {
|
|
$userParam = $&;
|
|
$userParam =~ s/ *param="*//;
|
|
$userParam =~ s/"//;
|
|
}
|
|
else {
|
|
$userParam = '';
|
|
}
|
|
$value = $tagVals{$name};
|
|
|
|
#check to see if there's an iteration
|
|
#if so, check to see if a repeater with this name exists
|
|
if ($iteration ne '') {
|
|
# return $name;
|
|
if (repeaterExists($name)) {
|
|
$value = eval('$' . $name . "[$iteration]");
|
|
$name .= $iteration;
|
|
}
|
|
}
|
|
|
|
$_ = $value;
|
|
|
|
#if it starts with / then we'll assume it's a path to a server var
|
|
if (($_ ne '') && (/^\//) && ($iteration eq '')) {
|
|
my $messHash = adminprotolib::GetMessageHash();
|
|
$status = adminprotolib::EchoData($data, $messHash, $authheader, $qtssip, $qtssport, $value, $value);
|
|
|
|
if (($status == 500) and ($data =~ /Connection refused/) and ($displayedLoginMessage == 0)) {
|
|
|
|
$displayedLoginMessage = 1;
|
|
|
|
$wasAuth = 0;
|
|
|
|
my $loginText = '';
|
|
|
|
open(LOGINFILE, "start_server.html") or die "Can't open server start file!";
|
|
|
|
while ($line = <LOGINFILE>) {
|
|
|
|
$loginText .= $line;
|
|
|
|
}
|
|
|
|
close(LOGINFILE);
|
|
|
|
$loginText = parseTags($loginText);
|
|
|
|
&cgilib::PrintOKTextHeader($servername);
|
|
|
|
print $loginText;
|
|
|
|
return 0;
|
|
|
|
}
|
|
if ($status == 401) {
|
|
my $isAuthenticated = 0;
|
|
|
|
if ($wasAuth == (-1)) {
|
|
$value = '';
|
|
return '';
|
|
}
|
|
|
|
# only try default authentication if setup assistant on mac os x
|
|
if (($^O eq "darwin") and (-e "index.html") and ($ENV{"REMOTE_HOST"} eq '127.0.0.1') and (MacQTGroupsContainsAdminGroup() == 0)) {
|
|
if (wasAuth >= 0) { # first pass
|
|
open(LOGINFILE, "setup_assistant.html");
|
|
my $loginText = '';
|
|
while ($line = <LOGINFILE>) {
|
|
$loginText .= $line;
|
|
}
|
|
close(LOGINFILE);
|
|
$wasAuth = (-1);
|
|
$loginText = parseTags($loginText);
|
|
&cgilib::PrintOKTextHeader($servername);
|
|
print $loginText;
|
|
return 0;
|
|
}
|
|
}
|
|
if (($displayedLoginMessage == 0) && ($isAuthenticated == 0)) {
|
|
$displayedLoginMessage = 1;
|
|
# now using cookies to store password; return login page
|
|
my $loginText = '';
|
|
open(LOGINFILE, "login.html") or die "Can't open login file!";
|
|
while ($line = <LOGINFILE>) {
|
|
$loginText .= $line;
|
|
}
|
|
close(LOGINFILE);
|
|
$loginText = parseTags($loginText);
|
|
&cgilib::PrintOKTextHeader($servername);
|
|
print $loginText;
|
|
$wasAuth = 0;
|
|
return 0;
|
|
}
|
|
}
|
|
$value = $data;
|
|
}
|
|
|
|
# if it starts with = then we'll evaluate it, replacing stuff first
|
|
# small possibility for nasty recursion exists here
|
|
# be sure not to include another evaluating tag inside this one
|
|
$_ = $value;
|
|
if (/^=/) {
|
|
$value =~ s/^=//;
|
|
$value = parseTags($value);
|
|
$value = eval($value);
|
|
}
|
|
|
|
# format value
|
|
$value = runFormatter($value, $format, $userParam, $name);
|
|
|
|
$final_value = $tagTypes{$type};
|
|
if ($final_value eq '') {
|
|
$final_value = $tagTypes{'plaintext'};
|
|
}
|
|
$final_value =~ s/<value\/>/$value/gi;
|
|
$final_value =~ s/<name\/>/$name/gi;
|
|
$final_value =~ s/<param\/>/$userParam/gi;
|
|
$final_value =~ s/<filename\/>/$filename/gi;
|
|
|
|
$_ = $final_value;
|
|
return $final_value;
|
|
}
|
|
|
|
#this routine replaces localized strings from the messages file
|
|
sub foundString {
|
|
my $tagAttributes = $_[0];
|
|
my $endTagSlash = $_[1];
|
|
my $singleTagSlash = $_[2];
|
|
my $name = '';
|
|
$_ = $tagAttributes;
|
|
if (/ name="[^"]*"| name=[^ (\/>)]*/si) {
|
|
$name = $&;
|
|
$name =~ s/ *name="*//;
|
|
$name =~ s/"//;
|
|
}
|
|
my $messHash = adminprotolib::GetMessageHash();
|
|
my %messages = %$messHash;
|
|
my $QTName = 'QT' . $name;
|
|
if (($^O eq "darwin") and ($messages{$QTName} ne '')) {
|
|
return $messages{$QTName};
|
|
}
|
|
return "$messages{$name}";
|
|
}
|
|
|
|
#this routine calls foundTag for each tag found.
|
|
sub parseTags {
|
|
$_[0] =~ s{ <qtssrepeater ( .*? ) > ( .*?) </qtssrepeater> }
|
|
{ expandRepeater($1, $2) }isgxe;
|
|
$_[0] =~ s{ < ( /*? ) qtssobject ( .*? ) (/*?) >}
|
|
{ foundTag($2, $1, $3) }isgxe;
|
|
$_[0] =~ s{ < ( /*? ) qtssstring ( .*? ) (/*?) >}
|
|
{ foundString($2, $1, $3) }isgxe;
|
|
return "$_[0]";
|
|
}
|
|
|
|
sub StartStopServer {
|
|
my $messageHash = &adminprotolib::GetMessageHash();
|
|
my $data = "";
|
|
my $status = &adminprotolib::EchoData($data, $messageHash, $authheader, $qtssip, $qtssport, "/modules/admin/server/qtssSvrState", "/server/qtssSvrState");
|
|
# if the server is not running, launch process
|
|
if($status == 200) {
|
|
# if server is running, then put it in idle mode or if server is idle/not running, then put it in running mode
|
|
if($data == 1) {
|
|
$status = &adminprotolib::SetAttribute($data, $messageHash, $authheader, $qtssip, $qtssport, "/admin/server/qtssSvrState", 5);
|
|
}
|
|
else {
|
|
$status = &adminprotolib::SetAttribute($data, $messageHash, $authheader, $qtssip, $qtssport, "/admin/server/qtssSvrState", 1);
|
|
}
|
|
}
|
|
}
|
|
|
|
sub SaveGeneralSettings {
|
|
my $messHash = adminprotolib::GetMessageHash();
|
|
my %messages = %$messHash;
|
|
my $settingsPath = '/admin/server/qtssSvrPreferences/';
|
|
my $data = '';
|
|
my $configFilePath = $ENV{"QTSSADMINSERVER_CONFIG"};
|
|
my $sslValue = $query->{'adminSSL'};
|
|
my $autoStartValue = $query->{'qtssExtraGenSettings0'};
|
|
my $name = '';
|
|
my $val = '';
|
|
|
|
if ($sslValue ne '1') {
|
|
$sslValue = '0';
|
|
}
|
|
|
|
if ($autoStartValue ne '1') {
|
|
$autoStartValue = '0';
|
|
}
|
|
|
|
if ($query->{'qtssMovieFolder'} ne $query->{'qtssMovieFolder_shadow'}) {
|
|
$status = &adminprotolib::SetAttribute($data, $messHash, $authheader, $qtssip, $qtssport, $settingsPath."movie_folder", $query->{'qtssMovieFolder'});
|
|
}
|
|
|
|
if ($query->{'qtssMaxConn'} ne $query->{'qtssMaxConn_shadow'}) {
|
|
$status = &adminprotolib::SetAttribute($data, $messHash, $authheader, $qtssip, $qtssport, $settingsPath."maximum_connections", $query->{'qtssMaxConn'});
|
|
}
|
|
|
|
if (($query->{'bpsinput'} ne $query->{'bpsinput_shadow'}) or ($query->{'kbpstype'} ne $query->{'kbpstype_shadow'})) {
|
|
my $amt = $query->{'bpsinput'};
|
|
if ($query->{'kbpstype'} eq 'mbps') {
|
|
$amt = $amt * 1024
|
|
}
|
|
$status = &adminprotolib::SetAttribute($data, $messHash, $authheader, $qtssip, $qtssport, $settingsPath."maximum_bandwidth", $amt);
|
|
}
|
|
|
|
if ($query->{'qtssAuthScheme'} ne $query->{'qtssAuthScheme_shadow'}) {
|
|
$status = &adminprotolib::SetAttribute($data, $messHash, $authheader, $qtssip, $qtssport, $settingsPath."authentication_scheme", $query->{'qtssAuthScheme'});
|
|
}
|
|
|
|
if ($sslValue ne parseForSSL()) {
|
|
$configLine = qq(ssl=$sslValue\n);
|
|
if(!(-e $configFilePath)) {
|
|
open(CONFIGFILE, ">$configFilePath");
|
|
print CONFIGFILE $configLine;
|
|
close(CONFIGFILE);
|
|
FixFileGroup($configFilePath);
|
|
if($sslValue == 1)
|
|
{
|
|
$ENV{"HTTPS"} = "ON";
|
|
}
|
|
else
|
|
{
|
|
$ENV{"HTTPS"} = "OFF";
|
|
}
|
|
}
|
|
else {
|
|
if( -r $configFilePath && -w _) {
|
|
$tmpname = $configFilePath . ".tmp";
|
|
open(TEMPFILE, ">$tmpname");
|
|
open(CONFIGFILE, "<$configFilePath");
|
|
while($line = <CONFIGFILE>) {
|
|
$_ = $line;
|
|
chop;
|
|
if (/^#/ || !/\S/) {
|
|
print TEMPFILE $line;
|
|
next;
|
|
}
|
|
/^([^=]+)=(.*)$/;
|
|
$name = $1; $val = $2;
|
|
$name =~ s/^\s+//g; $name =~ s/\s+$//g;
|
|
$val =~ s/^\s+//g; $val =~ s/\s+$//g;
|
|
if($name eq "ssl") {
|
|
$val = $sslValue;
|
|
}
|
|
$config{$name} = $val;
|
|
print TEMPFILE qq($name=$val\n);
|
|
}
|
|
if(!defined($config{'ssl'})) {
|
|
print TEMPFILE $configLine;
|
|
}
|
|
close(CONFIGFILE);
|
|
close(TEMPFILE);
|
|
rename $tmpname, $configFilePath;
|
|
if($sslValue == 1)
|
|
{
|
|
$ENV{"HTTPS"} = "ON";
|
|
}
|
|
else
|
|
{
|
|
$ENV{"HTTPS"} = "OFF";
|
|
}
|
|
}
|
|
else {
|
|
print STDERR "couldn't open $configFilePath for writing\n";
|
|
}
|
|
}
|
|
}
|
|
|
|
$confirmMessage = $messages{'GenSetSettingsSavedText'};
|
|
}
|
|
|
|
sub RunAssistant {
|
|
my $messHash = adminprotolib::GetMessageHash();
|
|
my %messages = %$messHash;
|
|
my $settingsPath = '/admin/server/qtssSvrPreferences/';
|
|
my $MP3BroadcastPasswordPath = "/admin/server/qtssSvrModuleObjects/QTSSMP3StreamingModule/qtssModPrefs/mp3_broadcast_password";
|
|
my $data = '';
|
|
my $configFilePath = $ENV{"QTSSADMINSERVER_CONFIG"};
|
|
my $sslValue = $query->{'assistSSL'};
|
|
my $name = '';
|
|
my $val = '';
|
|
|
|
if ($sslValue ne '1') {
|
|
$sslValue = '0';
|
|
}
|
|
|
|
# set MP3 Broadcast Password
|
|
|
|
$status = &adminprotolib::SetAttribute($data, $messHash, $authheader, $qtssip, $qtssport, $MP3BroadcastPasswordPath, $query->{'assistMP3Pass'});
|
|
|
|
# set media folder
|
|
|
|
$status = &adminprotolib::SetAttribute($data, $messHash, $authheader, $qtssip, $qtssport, $settingsPath."movie_folder", $query->{'assistMovieFolder'});
|
|
|
|
# set streaming on port 80
|
|
|
|
SavePortSettings();
|
|
$confirmMessage = ''; # reset the confirm message
|
|
|
|
# set SSL on/off
|
|
|
|
$configLine = qq(ssl=$sslValue\n);
|
|
if(!(-e $configFilePath)) {
|
|
open(CONFIGFILE, ">$configFilePath");
|
|
print CONFIGFILE $configLine;
|
|
close(CONFIGFILE);
|
|
FixFileGroup($configFilePath);
|
|
if($sslValue == 1)
|
|
{
|
|
$ENV{"HTTPS"} = "ON";
|
|
}
|
|
else
|
|
{
|
|
$ENV{"HTTPS"} = "OFF";
|
|
}
|
|
}
|
|
else {
|
|
if( -r $configFilePath && -w _) {
|
|
$tmpname = $configFilePath . ".tmp";
|
|
open(TEMPFILE, ">$tmpname");
|
|
open(CONFIGFILE, "<$configFilePath");
|
|
while($line = <CONFIGFILE>) {
|
|
$_ = $line;
|
|
chop;
|
|
if (/^#/ || !/\S/) {
|
|
print TEMPFILE $line;
|
|
next;
|
|
}
|
|
/^([^=]+)=(.*)$/;
|
|
$name = $1; $val = $2;
|
|
$name =~ s/^\s+//g; $name =~ s/\s+$//g;
|
|
$val =~ s/^\s+//g; $val =~ s/\s+$//g;
|
|
if($name eq "ssl") {
|
|
$val = $sslValue;
|
|
}
|
|
$config{$name} = $val;
|
|
print TEMPFILE qq($name=$val\n);
|
|
}
|
|
if(!defined($config{'ssl'})) {
|
|
print TEMPFILE $configLine;
|
|
}
|
|
close(CONFIGFILE);
|
|
close(TEMPFILE);
|
|
rename $tmpname, $configFilePath;
|
|
if($sslValue == 1)
|
|
{
|
|
$ENV{"HTTPS"} = "ON";
|
|
}
|
|
else
|
|
{
|
|
$ENV{"HTTPS"} = "OFF";
|
|
}
|
|
}
|
|
else {
|
|
print STDERR "couldn't open $configFilePath for writing\n";
|
|
}
|
|
}
|
|
}
|
|
|
|
sub SavePortSettings {
|
|
my $messHash = adminprotolib::GetMessageHash();
|
|
my %messages = %$messHash;
|
|
my $data = '';
|
|
my $settingsPath = '/admin/server/qtssSvrPreferences/';
|
|
|
|
if ($query->{'qtssIsStreamingOn80'} ne $query->{'qtssIsStreamingOn80_shadow'}) {
|
|
if($query->{'qtssIsStreamingOn80'} eq "true") {
|
|
# set the pref
|
|
$status = &adminprotolib::AddValueToAttribute($data, $messHash, $authheader, $qtssip, $qtssport, $settingsPath."rtsp_port", 80);
|
|
# find out where the pid file is
|
|
my $pidfileloc = '';
|
|
my $status = &adminprotolib::EchoData($pidfileloc, $messageHash, $authheader, $qtssip, $qtssport, "/modules/admin/server/qtssSvrPreferences/pid_file", "/server/qtssSvrPreferences/pid_file");
|
|
# if the pid file exists...
|
|
if (-e $pidfileloc) {
|
|
# read in the file into an array
|
|
my @splitPidFile = ();
|
|
my $line;
|
|
if (open(PIDFILE, $pidfileloc)) {
|
|
while ($line = <PIDFILE>) {
|
|
push(@splitPidFile, $line);
|
|
}
|
|
close(PIDFILE);
|
|
}
|
|
if (scalar(@splitPidFile) > 0) {
|
|
if ($splitPidFile[1] ne '') {
|
|
kill 2, $splitPidFile[1];
|
|
sleep(2);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
$status = &adminprotolib::DeleteValueFromAttribute($data, $messHash, $authheader, $qtssip, $qtssport, $settingsPath."rtsp_port", 80);
|
|
}
|
|
}
|
|
|
|
$confirmMessage = $messages{'PortSetSavedText'};
|
|
}
|
|
|
|
sub SaveLogSettings {
|
|
my $messHash = adminprotolib::GetMessageHash();
|
|
my %messages = %$messHash;
|
|
my $errorPath = "/admin/server/qtssSvrPreferences/";
|
|
my $accessPath = "/admin/server/qtssSvrModuleObjects/QTSSAccessLogModule/qtssModPrefs/";
|
|
my $data = '';
|
|
$nextFilename = 'log_settings.html';
|
|
|
|
if ($query->{'qtssErrorLogging'} ne $query->{'qtssErrorLogging_shadow'}) {
|
|
if ($query->{'qtssErrorLogging'} eq 'true') {
|
|
$status = &adminprotolib::SetAttribute($data, $messHash, $authheader, $qtssip, $qtssport, $errorPath."error_logging", true);
|
|
}
|
|
else {
|
|
$status = &adminprotolib::SetAttribute($data, $messHash, $authheader, $qtssip, $qtssport, $errorPath."error_logging", false);
|
|
}
|
|
}
|
|
|
|
if ($query->{'qtssErrorLogInterval'} ne $query->{'qtssErrorLogInterval_shadow'}) {
|
|
$status = &adminprotolib::SetAttribute($data, $messHash, $authheader, $qtssip, $qtssport, $errorPath."error_logfile_interval", $query->{'qtssErrorLogInterval'});
|
|
}
|
|
|
|
if ($query->{'qtssErrorLogSize'} ne $query->{'qtssErrorLogSize_shadow'}) {
|
|
$status = &adminprotolib::SetAttribute($data, $messageHash, $authheader, $qtssip, $qtssport, $errorPath."error_logfile_size", ($query->{'qtssErrorLogSize'} * 1024));
|
|
}
|
|
|
|
if ($query->{'qtssRequestLogging'} ne $query->{'qtssRequestLogging_shadow'}) {
|
|
if ($query->{'qtssRequestLogging'} eq 'true') {
|
|
$status = &adminprotolib::SetAttribute($data, $messHash, $authheader, $qtssip, $qtssport, $accessPath."request_logging", true);
|
|
}
|
|
else {
|
|
$status = &adminprotolib::SetAttribute($data, $messHash, $authheader, $qtssip, $qtssport, $accessPath."request_logging", false);
|
|
}
|
|
}
|
|
|
|
if ($query->{'qtssRequestLogInterval'} ne $query->{'qtssRequestLogInterval_shadow'}) {
|
|
$status = &adminprotolib::SetAttribute($data, $messHash, $authheader, $qtssip, $qtssport, $accessPath."request_logfile_interval", $query->{'qtssRequestLogInterval'});
|
|
}
|
|
|
|
if ($query->{'qtssRequestLogSize'} ne $query->{'qtssRequestLogSize_shadow'}) {
|
|
$status = &adminprotolib::SetAttribute($data, $messageHash, $authheader, $qtssip, $qtssport, $accessPath."request_logfile_size", ($query->{'qtssRequestLogSize'} * 1024));
|
|
}
|
|
|
|
$filename = 'log_settings.html';
|
|
$confirmMessage = $messages{'LogSetSavedText'};
|
|
}
|
|
|
|
sub ChangePassword {
|
|
my $messHash = adminprotolib::GetMessageHash();
|
|
my %messages = %$messHash;
|
|
my $usersFileAttributePath = "/server/qtssSvrModuleObjects/QTSSAccessModule/qtssModPrefs/modAccess_usersfilepath";
|
|
my $groupsFileAttributePath = "/server/qtssSvrModuleObjects/QTSSAccessModule/qtssModPrefs/modAccess_groupsfilepath";
|
|
my $usersFilePath = '';
|
|
my $groupsFilePath = '';
|
|
my $qtssPasswdName = $ENV{"QTSSADMINSERVER_QTSSQTPASSWD"};
|
|
my $data = '';
|
|
my $line = '';
|
|
my $oldUsername = $query->{'old_username'};
|
|
my $newUsername = $query->{'new_user'};
|
|
my $groupsFileText = '';
|
|
my $usersFileText = '';
|
|
$nextFilename = 'change_password.html';
|
|
|
|
# if username or password is blank
|
|
if (($query->{'new_user'} eq '') or ($query->{'new_password1'} eq '')) {
|
|
$dialogHeader = $messages{'SetupAssistNoUsernameHeader'};
|
|
$dialogText = $messages{'SetupAssistNoUsername'};
|
|
return;
|
|
}
|
|
|
|
# if username has more than 255 characters
|
|
if (length($query->{'new_user'}) > 255) {
|
|
$dialogHeader = $messages{'ChPassUsernameNotLongerThan255Header'};
|
|
$dialogText = $messages{'ChPassUsernameNotLongerThan255Text'};
|
|
return;
|
|
}
|
|
|
|
# if username has a colon
|
|
if ($query->{'new_user'} =~ /:/) {
|
|
$dialogHeader = $messages{'ChPassUsernameCannotHaveColonHeader'};
|
|
$dialogText = $messages{'ChPassUsernameCannotHaveColonText'};
|
|
return;
|
|
}
|
|
|
|
# if username or password has a single or a double quote
|
|
if ( ($query->{'new_user'} =~ /['"]/) || ($query->{'new_password1'} =~ /['"]/) ) {
|
|
$dialogHeader = $messages{'ChPassCannotHaveQuotesHeader'};
|
|
$dialogText = $messages{'ChPassCannotHaveQuotesText'};
|
|
return;
|
|
}
|
|
|
|
# if password has more than 80 characters
|
|
if (length($query->{'new_password1'}) > 80) {
|
|
$dialogHeader = $messages{'ChPassNotLongerThan80Header'};
|
|
$dialogText = $messages{'ChPassNotLongerThan80Text'};
|
|
return;
|
|
}
|
|
|
|
# if old username:password doesn't match the current username:password
|
|
if (encodeBase64($oldUsername.':'.$query->{'old_password'}) ne getCookie('qtsspassword')) {
|
|
$dialogHeader = $messages{'ChPassOldPasswdWrongHeader'};
|
|
$dialogText = $messages{'ChPassOldPasswdWrongText'};
|
|
return;
|
|
}
|
|
|
|
# if new password #1 and new password #2 don't match
|
|
if ($query->{'new_password1'} ne $query->{'new_password2'}) {
|
|
$dialogHeader = $messages{'ChPassNoMatchHeader'};
|
|
$dialogText = $messages{'ChPassNoMatchText'};
|
|
return;
|
|
}
|
|
|
|
my $status = &adminprotolib::EchoData($groupsFilePath, $messHash, $authheader, $qtssip, $qtssport, "/modules/admin$groupsFileAttributePath", "/modules/admin$groupsFileAttributePath");
|
|
|
|
if ($status != 200) {
|
|
$dialogHeader = $messages{'ChPassErrorHeader'};
|
|
$dialogText = $messages{'ChPassErrorText'}." ($status - $data)";
|
|
return;
|
|
}
|
|
|
|
$status = &adminprotolib::EchoData($usersFilePath, $messHash, $authheader, $qtssip, $qtssport, "/modules/admin$usersFileAttributePath", "/modules/admin$usersFileAttributePath");
|
|
|
|
if ($status != 200) {
|
|
$dialogHeader = $messages{'ChPassErrorHeader'};
|
|
$dialogText = $messages{'ChPassErrorText'}." ($status - $data)";
|
|
return;
|
|
}
|
|
|
|
open(FILEHDL, "$groupsFilePath") or die "Can't open groups file '$groupsFilePath'!";
|
|
while ($line = <FILEHDL>) {
|
|
$groupsFileText .= $line;
|
|
}
|
|
close(FILEHDL);
|
|
my $quotedOldUsername = quotemeta($oldUsername);
|
|
$groupsFileText =~ s/([ \t:]+)$quotedOldUsername([\r\n\s]+)/$1$newUsername$2/;
|
|
|
|
$status = &adminprotolib::SetPassword($data, $messageHash, $authheader, $qtssip, $qtssport, $usersFileAttributePath, $query->{'new_password1'}, $qtssPasswdName, $newUsername);
|
|
sleep(2);
|
|
|
|
if ($status != 200) {
|
|
$dialogHeader = $messages{'ChPassErrorHeader'};
|
|
$dialogText = $messages{'ChPassErrorText'}." ($status - $data)";
|
|
return;
|
|
}
|
|
|
|
open(FILEHDL, ">$groupsFilePath") or die "Can't open groups file '$groupsFilePath'!";
|
|
print FILEHDL $groupsFileText;
|
|
close(FILEHDL);
|
|
FixFileGroup($groupsFilePath);
|
|
|
|
$newcookieval = encodeBase64($newUsername.':'.$query->{'new_password1'});
|
|
$cookie = 'qtsspassword='.$newcookieval.';path=/';
|
|
$auth = $newcookieval;
|
|
$authheader = "Authorization: Basic $auth\r\n";
|
|
|
|
if ($oldUsername ne $newUsername)
|
|
{
|
|
&adminprotolib::DeleteUsername($data, $messageHash, $authheader, $qtssip, $qtssport, $usersFileAttributePath, $qtssPasswdName, $oldUsername);
|
|
}
|
|
|
|
# $confirmMessage = $messages{'ChPassSavedText'};
|
|
$filename = 'change_password_redirect.html';
|
|
|
|
}
|
|
|
|
sub ChangeBroadcastPassword {
|
|
my $messHash = adminprotolib::GetMessageHash();
|
|
my %messages = %$messHash;
|
|
my $filedelim = &playlistlib::GetFileDelimChar();
|
|
my $moviesFolderPath;
|
|
my $status = &adminprotolib::EchoData($moviesFolderPath, $messHash, $authheader, $qtssip, $qtssport, "/modules/admin/server/qtssSvrPreferences/movie_folder", "movie_folder");
|
|
my $accessFilename;
|
|
$status = &adminprotolib::EchoData($accessFilename, $messHash, $authheader, $qtssip, $qtssport, "/modules/admin/server/qtssSvrModuleObjects/QTSSAccessModule/qtssModPrefs/modAccess_qtaccessfilename", "modAccess_qtaccessfilename");
|
|
my $usersFilename;
|
|
$status = &adminprotolib::EchoData($usersFilename, $messHash, $authheader, $qtssip, $qtssport, "/modules/admin/server/qtssSvrModuleObjects/QTSSAccessModule/qtssModPrefs/modAccess_usersfilepath", "modAccess_usersfilepath");
|
|
my $groupsFilename;
|
|
$status = &adminprotolib::EchoData($groupsFilename, $messHash, $authheader, $qtssip, $qtssport, "/modules/admin/server/qtssSvrModuleObjects/QTSSAccessModule/qtssModPrefs/modAccess_groupsfilepath", "modAccess_groupsfilepath");
|
|
$moviesFolderPath =~ s/[\/\\]$//o;
|
|
my $filename = "$moviesFolderPath$filedelim$accessFilename";
|
|
my $viewingUsersArrayRef = &passwordutils::GetViewingRestrictionsFromFile($filename);
|
|
my @viewingUsersArray = @$viewingUsersArrayRef;
|
|
my $viewingUsersString = join(' ', @viewingUsersArray);
|
|
my $broadcastUsersArrayRef = &passwordutils::GetBroadcastRestrictionsFromFile($filename);
|
|
my @broadcastUsersArray = @$broadcastUsersArrayRef;
|
|
my $oldBroadcastUser = '';
|
|
my $broadcastRestrictionString = '';
|
|
my ($currentAdminUsername, $currentAdminPass) = split(/:/, b64decode($auth));
|
|
my $qtpasswdpath = $ENV{"QTSSADMINSERVER_QTSSQTPASSWD"};
|
|
|
|
if ($broadcastUsersArray[1] eq 'user') {
|
|
$oldBroadcastUser = $broadcastUsersArray[2];
|
|
}
|
|
|
|
# change the password in the passwords file
|
|
# work on a copy if it's the current admin user
|
|
if ($query->{'new_user'} ne $oldBroadcastUser) {
|
|
if ($oldBroadcastUser ne $currentAdminUsername) {
|
|
&passwordutils::DeleteUser($qtpasswdpath, $usersFilename, $groupsFilename, $oldBroadcastUser);
|
|
}
|
|
if (($query-{'allowUnrestrictedBroadcast'} ne '1') && ($query->{'new_user'} ne '')) {
|
|
&passwordutils::AddOrEditBroadcastUser($qtpasswdpath, $usersFilename, $query->{'new_user'}, $query->{'new_password1'});
|
|
}
|
|
}
|
|
|
|
if ($query->{'allowUnrestrictedBroadcast'} eq '1') {
|
|
$broadcastRestrictionString = "require any-user";
|
|
}
|
|
elsif (($query->{'new_user'} ne '') && ($query->{'new_password1'} ne '')) {
|
|
$broadcastRestrictionString = "require user " . $query->{'new_user'};
|
|
}
|
|
my $viewingRestrictionString = join(' ', @$viewingUsersArrayRef);
|
|
#&passwordutils::WriteRestrictionsToFile($filename, $broadcastRestrictionString, $viewingRestrictionString);
|
|
# RemoveRestrictionsFile is for QTSS to sync with the server admin. Use WriteRestrictionsToFile above on Darwin Web Admins
|
|
&passwordutils::RemoveRestrictionsFile($filename);
|
|
|
|
$confirmMessage = $messages{'ChMP3PassSavedText'};
|
|
$filename = 'general_settings.html';
|
|
}
|
|
|
|
sub ChangeMP3Password {
|
|
my $messHash = adminprotolib::GetMessageHash();
|
|
my %messages = %$messHash;
|
|
my $MP3BroadcastPasswordPath = "/admin/server/qtssSvrModuleObjects/QTSSMP3StreamingModule/qtssModPrefs/mp3_broadcast_password";
|
|
my $qtssPasswdName = $ENV{"QTSSADMINSERVER_QTSSQTPASSWD"};
|
|
my $qtssAdmin = $ENV{"QTSSADMINSERVER_QTSSADMIN"};
|
|
my $data = '';
|
|
$nextFilename = 'change_mp3_password.html';
|
|
|
|
if ($query->{'new_password1'} ne $query->{'new_password2'}) {
|
|
$dialogHeader = $messages{'ChMP3PassNoMatchHeader'};
|
|
$dialogText = $messages{'ChMP3PassNoMatchText'};
|
|
return;
|
|
}
|
|
|
|
$status = &adminprotolib::SetAttribute($data, $messHash, $authheader, $qtssip, $qtssport, $MP3BroadcastPasswordPath, $query->{'new_password1'});
|
|
|
|
$confirmMessage = $messages{'ChMP3PassSavedText'};
|
|
$filename = $query->{'replaceFilename'};
|
|
if ($filename eq '') {
|
|
$filename = 'general_settings.html';
|
|
}
|
|
}
|
|
|
|
# AssistSetPassword
|
|
# returns 0 => failure
|
|
# 1 => success
|
|
sub AssistSetPassword {
|
|
my $messHash = adminprotolib::GetMessageHash();
|
|
my %messages = %$messHash;
|
|
my $usersFileAttributePath = "/server/qtssSvrModuleObjects/QTSSAccessModule/qtssModPrefs/modAccess_usersfilepath";
|
|
my $groupsFileAttributePath = "/server/qtssSvrModuleObjects/QTSSAccessModule/qtssModPrefs/modAccess_groupsfilepath";
|
|
my $usersFilePath = '';
|
|
my $groupsFilePath = '';
|
|
my $qtssPasswdName = $ENV{"QTSSADMINSERVER_QTSSQTPASSWD"};
|
|
my $qtssAdmin = $ENV{"QTSSADMINSERVER_QTSSADMIN"};
|
|
my $data = '';
|
|
my $line = '';
|
|
my $newUsername = $query->{'new_user'};
|
|
my $newPassword = $query->{'new_password1'};
|
|
my ($oldUsername, $authpass) = split(/:/, b64decode($auth));
|
|
$nextFilename = 'setup_assistant.html';
|
|
|
|
# if username or password is blank
|
|
if (($query->{'new_user'} eq '') or ($query->{'new_password1'} eq '')) {
|
|
$dialogHeader = $messages{'SetupAssistNoUsernameHeader'};
|
|
$dialogText = $messages{'SetupAssistNoUsername'};
|
|
return 0;
|
|
}
|
|
|
|
# if username has more than 255 characters
|
|
if (length($query->{'new_user'}) > 255) {
|
|
$dialogHeader = $messages{'ChPassUsernameNotLongerThan255Header'};
|
|
$dialogText = $messages{'ChPassUsernameNotLongerThan255Text'};
|
|
return 0;
|
|
}
|
|
|
|
# if username has a colon
|
|
if ($query->{'new_user'} =~ /:/) {
|
|
$dialogHeader = $messages{'ChPassUsernameCannotHaveColonHeader'};
|
|
$dialogText = $messages{'ChPassUsernameCannotHaveColonText'};
|
|
return 0;
|
|
}
|
|
|
|
# if username or password has a single quote or a double quote
|
|
if ( ($query->{'new_user'} =~ /['"]/) || ($query->{'new_password1'} =~ /['"]/) ) {
|
|
$dialogHeader = $messages{'ChPassCannotHaveQuotesHeader'};
|
|
$dialogText = $messages{'ChPassCannotHaveQuotesText'};
|
|
return 0;
|
|
}
|
|
|
|
# if password has more than 80 characters
|
|
if (length($query->{'new_password1'}) > 80) {
|
|
$dialogHeader = $messages{'ChPassNotLongerThan80Header'};
|
|
$dialogText = $messages{'ChPassNotLongerThan80Text'};
|
|
return 0;
|
|
}
|
|
|
|
# if new password #1 and new password #2 don't match
|
|
if ($query->{'new_password1'} ne $query->{'new_password2'}) {
|
|
$dialogHeader = $messages{'ChPassNoMatchHeader'};
|
|
$dialogText = $messages{'ChPassNoMatchText'};
|
|
return 0;
|
|
}
|
|
|
|
my $status = 200;
|
|
|
|
if (($^O eq "darwin") and (-e "index.html") and (MacQTGroupsContainsAdminGroup() == 0)) {
|
|
my $line = '';
|
|
$groupsFileText = '';
|
|
if (-e '/Library/QuickTimeStreaming/Config/qtgroups') {
|
|
open(GROUPSFILE, '/Library/QuickTimeStreaming/Config/qtgroups') or die("Can't open groups file!");
|
|
while ($line = <GROUPSFILE>) {
|
|
$groupsFileText .= $line;
|
|
}
|
|
close(GROUPSFILE);
|
|
}
|
|
$groupsFileText .= "admin: $newUsername\n";
|
|
$groupsFilePath = '/Library/QuickTimeStreaming/Config/qtgroups';
|
|
my $extraargs = '';
|
|
my $qtpasswdpath = $ENV{'QTSSADMINSERVER_QTSSQTPASSWD'};
|
|
if (!(-e '/Library/QuickTimeStreaming/Config/qtusers')) {
|
|
$extraargs = ' -c';
|
|
}
|
|
if(system("$qtpasswdpath$extraargs -p \'$newPassword\' \'$newUsername\'") != 0) {
|
|
$dialogHeader = $messages{'ChPassErrorHeader'};
|
|
$dialogText = $messages{'ChPassErrorText'};
|
|
return 0;
|
|
}
|
|
else {
|
|
$status = 200
|
|
}
|
|
}
|
|
else {
|
|
$status = &adminprotolib::EchoData($groupsFilePath, $messHash, $authheader, $qtssip, $qtssport, "/modules/admin$groupsFileAttributePath", "/modules/admin$groupsFileAttributePath");
|
|
|
|
if ($status == 401) {
|
|
$auth = encodeBase64('aGFja21l:aGFja21l');
|
|
$authheader = "Authorization: Basic $auth\r\n";
|
|
$oldUsername = 'aGFja21l';
|
|
$status = &adminprotolib::EchoData($groupsFilePath, $messHash, $authheader, $qtssip, $qtssport, "/modules/admin$groupsFileAttributePath", "/modules/admin$groupsFileAttributePath");
|
|
}
|
|
|
|
if ($status != 200) {
|
|
$dialogHeader = $messages{'ChPassErrorHeader'};
|
|
$dialogText = $messages{'ChPassErrorText'}." ($status - $data)";
|
|
return 0;
|
|
}
|
|
|
|
$status = &adminprotolib::EchoData($usersFilePath, $messHash, $authheader, $qtssip, $qtssport, "/modules/admin$usersFileAttributePath", "/modules/admin$usersFileAttributePath");
|
|
|
|
if ($status != 200) {
|
|
$dialogHeader = $messages{'ChPassErrorHeader'};
|
|
$dialogText = $messages{'ChPassErrorText'}." ($status - $data)";
|
|
return 0;
|
|
}
|
|
|
|
open(FILEHDL, "$groupsFilePath") or die "Can't open groups file '$groupsFilePath'!";
|
|
while ($line = <FILEHDL>) {
|
|
$groupsFileText .= $line;
|
|
}
|
|
close(FILEHDL);
|
|
|
|
my $quotedOldUsername = quotemeta($oldUsername);
|
|
$groupsFileText =~ s/([ \t:]+)$quotedOldUsername([\r\n\s]+)/$1$newUsername$2/;
|
|
|
|
$status = &adminprotolib::SetPassword($data, $messageHash, $authheader, $qtssip, $qtssport, $usersFileAttributePath, $query->{'new_password1'}, $qtssPasswdName, $newUsername);
|
|
|
|
if ($status != 200) {
|
|
$dialogHeader = $messages{'ChPassErrorHeader'};
|
|
$dialogText = $messages{'ChPassErrorText'}." ($status - $data)";
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
open(FILEHDL, ">$groupsFilePath") or die "Can't open groups file '$groupsFilePath'!";
|
|
print FILEHDL $groupsFileText;
|
|
close(FILEHDL);
|
|
FixFileGroup($groupsFileText);
|
|
|
|
# set the cookie and the auth header before calling DeleteUsername as the server expects the new username:password now
|
|
my $newcookieval = encodeBase64($newUsername.':'.$query->{'new_password1'});
|
|
$cookie = 'qtsspassword='.$newcookieval.'; path=/';
|
|
$auth = $newcookieval;
|
|
$authheader = "Authorization: Basic $auth\r\n";
|
|
|
|
if ($oldUsername ne $newUsername)
|
|
{
|
|
&adminprotolib::DeleteUsername($data, $messageHash, $authheader, $qtssip, $qtssport, $usersFileAttributePath, $qtssPasswdName, $oldUsername);
|
|
}
|
|
|
|
$dialogHeader = $messages{'ChPassSavedHeader'};
|
|
$dialogText = $messages{'ChPassSavedText'};
|
|
$filename = 'setup_assistant2.html';
|
|
|
|
return 1;
|
|
}
|
|
|
|
sub StartPlaylist {
|
|
my $messHash = adminprotolib::GetMessageHash();
|
|
my %messages = %$messHash;
|
|
my $curplaylist = $query->{'curplaylist'};
|
|
my $isRunning = &playlistlib::GetPlayListState($curplaylist);
|
|
my $filedelim = &playlistlib::GetFileDelimChar();
|
|
my $plroot = &playlistlib::GetPLRootDir();
|
|
my $filedelim = &playlistlib::GetFileDelimChar();
|
|
my $targ = '';
|
|
my $targline = '';
|
|
my $plfiletext = '';
|
|
my $success = 0;
|
|
my $targ = "$plroot$curplaylist$filedelim$curplaylist";
|
|
my $isRunning = &playlistlib::GetPlayListState($curplaylist);
|
|
|
|
# open the playlist and re-save it so that the MP3 broadcast password is updated if necessary
|
|
|
|
my $playlistdataref = &playlistlib::ParsePlayListEntry($curplaylist, $messHash);
|
|
my $movieDir = '';
|
|
my $mp3BroadcastPassword = '';
|
|
my $status = adminprotolib::EchoData($movieDir, $messHash, $authheader, $qtssip, $qtssport, "/modules/admin/server/qtssSvrPreferences/movie_folder", "/modules/admin/server/qtssSvrPreferences/movie_folder");
|
|
$status = adminprotolib::EchoData($mp3BroadcastPassword, $messHash, $authheader, $qtssip, $qtssport, "/modules/admin/server/qtssSvrModuleObjects/QTSSMP3StreamingModule/qtssModPrefs/mp3_broadcast_password", "/modules/admin/server/qtssSvrModuleObjects/QTSSMP3StreamingModule/qtssModPrefs/mp3_broadcast_password");
|
|
if (&playlistlib::CreatePlayListEntry($curplaylist, $playlistdataref, $movieDir, $mp3BroadcastPassword) == 0) {
|
|
$confirmMessage = '';
|
|
$filename = 'confirm.html';
|
|
$dialogHeader = $messages{'PLErrorHeader'};
|
|
$dialogText = $messages{'PLErrorHeader'};
|
|
$nextFilename = 'playlists.html';
|
|
return;
|
|
}
|
|
|
|
# playlist is re-saved
|
|
|
|
if ("$isRunning" ne 1) {
|
|
open(PLFILE, "$targ.config");
|
|
while ($targline = <PLFILE>) {
|
|
$plfiletext .= $targline;
|
|
}
|
|
close(PLFILE);
|
|
if ($plfiletext =~ /broadcast_genre /) {
|
|
$isMP3 = 1;
|
|
}
|
|
else {
|
|
$isMP3 = 0;
|
|
}
|
|
|
|
|
|
$success = &playlistlib::StartPlayList($curplaylist, $isMP3);
|
|
|
|
|
|
if ($success != 1) {
|
|
$filename = 'confirm.html';
|
|
$nextFilename = 'playlists.html';
|
|
$dialogHeader = $messages{'PLErrorHeader'};
|
|
$dialogText = $messages{'PLErrorText'};
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
# successfully started the playlist!
|
|
my $startfile = "$plroot$curplaylist$filedelim" . '.started';
|
|
# create a file in the playlist directory called .started
|
|
# which we shall delete when we stop the playlist later
|
|
open(STARTFILE, ">$startfile");
|
|
close(STARTFILE);
|
|
FixFileGroup($startfile);
|
|
chmod(0644, $startfile);
|
|
}
|
|
}
|
|
# $confirmMessage = $messages{'PLChangedText'};
|
|
}
|
|
|
|
sub StopPlaylist
|
|
{
|
|
my $messHash = adminprotolib::GetMessageHash();
|
|
my %messages = %$messHash;
|
|
my $plroot = &playlistlib::GetPLRootDir();
|
|
my $filedelim = &playlistlib::GetFileDelimChar();
|
|
my $curplaylist = $query->{'curplaylist'};
|
|
my $isRunning = &playlistlib::GetPlayListState($curplaylist);
|
|
my $filedelim = &playlistlib::GetFileDelimChar();
|
|
my $targ = '';
|
|
my $targline = '';
|
|
my $plfiletext = '';
|
|
my $targ = "$plroot$curplaylist$filedelim$curplaylist";
|
|
my $isRunning = &playlistlib::GetPlayListState($curplaylist);
|
|
|
|
if ("$isRunning" ne $startstop{$i})
|
|
{
|
|
# delete the file created when we started the playlist
|
|
# even if we don't succeed in stopping the playlist
|
|
# (which would only happen if we were reporting the wrong status
|
|
# and the playlist was already stopped)
|
|
my $startfile = "$plroot$curplaylist$filedelim" . '.started';
|
|
if ( -e $startfile)
|
|
{
|
|
unlink($startfile);
|
|
}
|
|
|
|
if (&playlistlib::StopPlayList($curplaylist) != 1)
|
|
{
|
|
$dialogHeader = $messages{'PLErrorHeader'};
|
|
$dialogText = $messages{'PLErrorText'};
|
|
return;
|
|
}
|
|
}
|
|
# $confirmMessage = $messages{'PLChangedText'};
|
|
}
|
|
|
|
sub ShowPlaylistLog {
|
|
my $curplaylist = $query->{'curplaylist'};
|
|
$playlistErrorLogText = &playlistlib::EmitPlayListErrLogFile($curplaylist);
|
|
}
|
|
|
|
sub PLOpenDir {
|
|
my $messHash = adminprotolib::GetMessageHash();
|
|
my %messages = %$messHash;
|
|
my $genreArrayRef = adminprotolib::GetGenreArray();
|
|
$curplaylist = $query->{'curplaylist'};
|
|
$movieDir = $query->{'submitcurrentdir'};
|
|
}
|
|
|
|
sub GetPlaylist {
|
|
my $messHash = adminprotolib::GetMessageHash();
|
|
my %messages = %$messHash;
|
|
my $genreArrayRef = adminprotolib::GetGenreArray();
|
|
$curplaylist = $query->{'curplaylist'};
|
|
my $playlistdataref = &playlistlib::ParsePlayListEntry($curplaylist, $messHash);
|
|
my @playlistdata = @$playlistdataref;
|
|
my $status = adminprotolib::EchoData($movieDir, $messHash, $authheader, $qtssip, $qtssport, "/modules/admin/server/qtssSvrPreferences/movie_folder", "/modules/admin/server/qtssSvrPreferences/movie_folder");
|
|
$currentDir = $movieDir;
|
|
$plfilename = $playlistdata[0];
|
|
$plmode = $playlistdata[1];
|
|
$pllogging = $playlistdata[2];
|
|
$plfilesref = $playlistdata[3];
|
|
@plfiles = @$plfilesref;
|
|
$plrep = $playlistdata[4];
|
|
$plgenre = $playlistdata[5];
|
|
$plbroadcastip = $playlistdata[6];
|
|
$plbroadcastusername = $playlistdata[7];
|
|
$plbroadcastpassword = $playlistdata[8];
|
|
$pltitle = $playlistdata[9];
|
|
if ($plgenre eq '') {
|
|
$isMP3 = 0;
|
|
$doctitle = $messages{'PLMoviePlaylistDetails'};
|
|
$extraFieldLabel = '';
|
|
$extraFieldHTML = '<input type=hidden name=PLGenre value="">';
|
|
$playlistUsernameHTML = '<tr><td align=left> </td><td align=right>'.$messages{'Username'}.'</td><td align=left><input type=text name=plbroadcastusername value="' . $plbroadcastusername . '"></td></tr>';
|
|
}
|
|
else {
|
|
$isMP3 = 1;
|
|
$doctitle = $messages{'PLMP3PlaylistDetails'};
|
|
$extraFieldLabel = $messages{'PLGenre'};
|
|
$extraFieldHTML = '<select name=PLGenre>'.&playlistlib::GetGenreOptions($plgenre, $messages{'PLDefaultGenre'}, $genreArrayRef).'</select>';
|
|
$playlistUsernameHTML = '';
|
|
}
|
|
if ($plbroadcastip eq '127.0.0.1') {
|
|
$plexternal = '0';
|
|
$plbroadcastusername = '';
|
|
$plbroadcastpassword = '';
|
|
}
|
|
else {
|
|
$plexternal = '1';
|
|
}
|
|
}
|
|
|
|
sub CreatePlaylist {
|
|
my $messHash = adminprotolib::GetMessageHash();
|
|
my %messages = %$messHash;
|
|
my $plroot = &playlistlib::GetPLRootDir();
|
|
my $fileDelimChar = &playlistlib::GetFileDelimChar();
|
|
my $movieDir = '';
|
|
my $mp3BroadcastPassword = '';
|
|
my $status = adminprotolib::EchoData($movieDir, $messHash, $authheader, $qtssip, $qtssport, "/modules/admin/server/qtssSvrPreferences/movie_folder", "/modules/admin/server/qtssSvrPreferences/movie_folder");
|
|
my $status = adminprotolib::EchoData($mp3BroadcastPassword, $messHash, $authheader, $qtssip, $qtssport, "/modules/admin/server/qtssSvrModuleObjects/QTSSMP3StreamingModule/qtssModPrefs/mp3_broadcast_password", "/modules/admin/server/qtssSvrModuleObjects/QTSSMP3StreamingModule/qtssModPrefs/mp3_broadcast_password");
|
|
my @plcontents = ();
|
|
my $item = '';
|
|
my $plname = $query->{'qtssCurPlaylistName'};
|
|
my $i = 2;
|
|
|
|
if ($plname eq '') {
|
|
# no playlist filename yet... means this is a new playlist
|
|
# set it to the playlist title
|
|
$plname = $query->{'qtssCurPlaylistTitle'};
|
|
# drop all non-alphanumeric characters
|
|
$plname =~ s/[^a-zA-Z0-9]//go;
|
|
if (($plname eq '') or (-e "$plroot$plname$fileDelimChar")) {
|
|
while (-e "$plroot$plname$fileDelimChar$i") {
|
|
$i++;
|
|
}
|
|
$plname = "$plname$i";
|
|
}
|
|
}
|
|
else {
|
|
if (-e "$plroot$plname$fileDelimChar$plname.err") {
|
|
unlink "$plroot$plname$fileDelimChar$plname.err";
|
|
}
|
|
}
|
|
|
|
$i = 0;
|
|
$nextFilename = 'playlists.html';
|
|
$confirmMessage = $messages{'PLCreatedText'};
|
|
my $qtssCurPlaylistURL = $plname.'.sdp';
|
|
if ($query->{'qtssCurPlaylistURL'} ne '') {
|
|
$qtssCurPlaylistURL = $query->{'qtssCurPlaylistURL'};
|
|
}
|
|
my $qtssCurPlaylistMode = $query->{'qtssCurPlaylistMode'};
|
|
my $playlistFiles = $query->{'submitplaylistfiles'};
|
|
$playlistFiles =~ s/%(..)/pack("c",hex($1))/ge;
|
|
@plcontents = split(/\t/, $playlistFiles);
|
|
my @submitplaylistweights = split(/\t/, $query->{'submitplaylistweights'});
|
|
foreach $item (@plcontents) {
|
|
$item = "$item:$submitplaylistweights[$i++]";
|
|
}
|
|
my $qtssCurPlaylistRep = '1';
|
|
if ($query->{'qtssCurPlaylistRep'} ne '') {
|
|
$qtssCurPlaylistRep = $query->{'qtssCurPlaylistRep'};
|
|
}
|
|
my $destipaddr = $query->{'plbroadcastip'};
|
|
my $broadcastusername = $query->{'plbroadcastusername'};
|
|
my $broadcastpassword = $query->{'plbroadcastpassword'};
|
|
if (($query->{'plexternal'} ne '1') or ($destipaddr eq '')) {
|
|
$destipaddr = '127.0.0.1';
|
|
$broadcastusername = '';
|
|
$broadcastpassword = '';
|
|
}
|
|
my @plsettings = ($qtssCurPlaylistURL,$qtssCurPlaylistMode,$query->{'pllogging'},\@plcontents,$qtssCurPlaylistRep,$query->{'PLGenre'},$destipaddr,$broadcastusername,$broadcastpassword,$query->{'qtssCurPlaylistTitle'});
|
|
if (&playlistlib::CreatePlayListEntry($plname, \@plsettings, $movieDir, $mp3BroadcastPassword) == 0) {
|
|
$confirmMessage = '';
|
|
$filename = 'confirm.html';
|
|
$dialogHeader = $messages{'PLCreateErrorHeader'};
|
|
$dialogText = $messages{'PLCreateErrorText'};
|
|
$nextFilename = 'playlists.html';
|
|
}
|
|
}
|
|
|
|
# NewPlaylist expects the var isMP3 to be set to 0 or 1
|
|
|
|
sub NewPlaylist {
|
|
my $messHash = adminprotolib::GetMessageHash();
|
|
my %messages = %$messHash;
|
|
my $genreArrayRef = &adminprotolib::GetGenreArray();
|
|
my @genreArray = @$genreArrayRef;
|
|
my $status = adminprotolib::EchoData($movieDir, $messHash, $authheader, $qtssip, $qtssport, "/modules/admin/server/qtssSvrPreferences/movie_folder", "/modules/admin/server/qtssSvrPreferences/movie_folder");
|
|
$currentDir = useDefaultIfBlank($query->{'currentdir'}, $movieDir);
|
|
$plrep = 1;
|
|
@plfiles = ();
|
|
$plrep = '1';
|
|
$curplaylist = '';
|
|
$pltitle = '';
|
|
$plfilename = '';
|
|
$plmode = '';
|
|
$pllogging = '';
|
|
$plbroadcastip = '127.0.0.1';
|
|
$plbroadcastusername = '';
|
|
$plbroadcastpassword = '';
|
|
if ($isMP3 == 1) {
|
|
$doctitle = $messages{'PLMP3PlaylistDetails'};
|
|
$extraFieldLabel = $messages{'PLGenre'};
|
|
$extraFieldHTML = '<select name=PLGenre>'.&playlistlib::GetGenreOptions('', $messages{'PLDefaultGenre'}, $genreArrayRef).'</select>';
|
|
$playlistUsernameHTML = '';
|
|
$pltitle = $messages{'PLDefaultPlaylistName'};
|
|
$plfilename = $messages{'PLDefaultMP3PlaylistMountPoint'};
|
|
}
|
|
else {
|
|
$doctitle = $messages{'PLMoviePlaylistDetails'};
|
|
$extraFieldLabel = '';
|
|
$extraFieldHTML = '';
|
|
$playlistUsernameHTML = '<tr><td align=left> </td><td align=right>'.$messages{'Username'}.'</td><td align=left><input type=text name=plbroadcastusername></td></tr>';
|
|
$pltitle = $messages{'PLDefaultPlaylistName'};
|
|
$plfilename = $messages{'PLDefaultMoviePlaylistSDP'};
|
|
}
|
|
}
|
|
|
|
sub RefreshPlaylistDir() {
|
|
my $messHash = adminprotolib::GetMessageHash();
|
|
my %messages = %$messHash;
|
|
my $genreArrayRef = &adminprotolib::GetGenreArray();
|
|
my @genreArray = @$genreArrayRef;
|
|
my $i = 0;
|
|
my $playlistFiles = $query->{'submitplaylistfiles'};
|
|
$playlistFiles =~ s/%(..)/pack("c",hex($1))/ge;
|
|
my @plcontents = split(/\t/, $playlistFiles);
|
|
my @submitplaylistweights = split(/\t/, $query->{'submitplaylistweights'});
|
|
@plfiles = ();
|
|
my $status = adminprotolib::EchoData($movieDir, $messHash, $authheader, $qtssip, $qtssport, "/modules/admin/server/qtssSvrPreferences/movie_folder", "/modules/admin/server/qtssSvrPreferences/movie_folder");
|
|
foreach $item (@plcontents) {
|
|
push(@plfiles, "$item:$submitplaylistweights[$i++]");
|
|
}
|
|
$currentDir = $query->{'submitcurrentdir'};
|
|
$currentDir =~ s/%(..)/pack("c",hex($1))/ge;
|
|
$query->{'submitcurrentdir'} = '';
|
|
$isMP3 = $query->{'isMP3'};
|
|
$plrep = $query->{'qtssCurPlaylistRep'};
|
|
$curplaylist = $query->{'qtssCurPlaylistName'};
|
|
$pltitle = $query->{'qtssCurPlaylistTitle'};
|
|
$plfilename = $query->{'qtssCurPlaylistURL'};
|
|
$plmode = $query->{'qtssCurPlaylistMode'};
|
|
$plrep = $query->{'qtssCurPlaylistRep'};
|
|
$plgenre = $query->{'PLGenre'};
|
|
$pllogging = $query->{'pllogging'};
|
|
$plbroadcastip = $query->{'plbroadcastip'};
|
|
$plbroadcastusername = $query->{'plbroadcastusername'};
|
|
$plbroadcastpassword = $query->{'plbroadcastpassword'};
|
|
|
|
if ($isMP3 == 0) {
|
|
$doctitle = $messages{'PLMoviePlaylistDetails'};
|
|
$extraFieldLabel = '';
|
|
$extraFieldHTML = '<input type=hidden name=PLGenre value="">';
|
|
$playlistUsernameHTML = '<tr><td> </td><td align=right>'.$messages{'Username'}.'</td><td><input type=text name=plbroadcastusername value="' . $plbroadcastusername . '"></td></tr>';
|
|
}
|
|
else {
|
|
$doctitle = $messages{'PLMP3PlaylistDetails'};
|
|
$extraFieldLabel = $messages{'PLGenre'};
|
|
$extraFieldHTML = '<select name=PLGenre>'.&playlistlib::GetGenreOptions($plgenre, $messages{'PLDefaultGenre'}, $genreArrayRef).'</select>';
|
|
$playlistUsernameHTML = '';
|
|
}
|
|
if (($plbroadcastip eq '127.0.0.1') or ($plbroadcastip eq '')) {
|
|
$plexternal = '0';
|
|
$plbroadcastusername = '';
|
|
$plbroadcastpassword = '';
|
|
}
|
|
else {
|
|
$plexternal = '1';
|
|
}
|
|
}
|
|
|
|
sub DeletePlaylist {
|
|
my $messHash = adminprotolib::GetMessageHash();
|
|
my %messages = %$messHash;
|
|
if (&playlistlib::RemovePlaylistDir($query->{'curplaylist'}) == 1) {
|
|
$confirmText = $messages{'PLDeleteText'};
|
|
}
|
|
else {
|
|
$filename = 'confirm.html';
|
|
$nextFilename = 'playlists.html';
|
|
$dialogHeader = $messages{'PLDeleteErrorHeader'};
|
|
$dialogText = $messages{'PLDeleteErrorText'};
|
|
}
|
|
}
|
|
|
|
sub ResetErrorLog {
|
|
my $chdelim = &playlistlib::GetFileDelimChar();
|
|
my $messHash = adminprotolib::GetMessageHash();
|
|
my %messages = %$messHash;
|
|
my $responseText = '';
|
|
my $status = adminprotolib::GetData($responseText, $messHash, $authheader, $qtssip, $qtssport, '/modules/admin/server/qtssSvrPreferences/error_logfile_dir');
|
|
$_ = $responseText;
|
|
$confirmMessage = 'redirect';
|
|
if (!(/error_logfile_dir="([^"]+)"/)) {
|
|
die('Error getting logfile dir.');
|
|
}
|
|
my $dirname = $1;
|
|
$status = adminprotolib::GetData($responseText, $messHash, $authheader, $qtssip, $qtssport, '/modules/admin/server/qtssSvrPreferences/error_logfile_name');
|
|
$_ = $responseText;
|
|
if (!(/error_logfile_name="([^"]+)"/)) {
|
|
die('Error getting filename.');
|
|
}
|
|
$logname = $1;
|
|
$logfilename = $dirname . $chdelim . $logname . '.log';
|
|
$logfilename =~ s/\/{2,}/\//g; # remove duplicate slashes
|
|
if (-e $logfilename) {
|
|
$rolldatestr = sprintf("%02d%02d%02d", sub {($_[5] % 100, $_[4]+1, $_[3])}->(localtime));
|
|
$rollfilenumber = 0;
|
|
$rollfilename = "$dirname$chdelim" . $logname . ".$rolldatestr" . '000.log';
|
|
while (-e $rollfilename) {
|
|
$rollfilenumber++;
|
|
$rollfilename = "$dirname$chdelim" . $logname . ".$rolldatestr" . sprintf("%03d", $rollfilenumber) . '.log';
|
|
}
|
|
$rollfilename =~ s/\/{2,}/\//g; # remove duplicate slashes
|
|
`/bin/mv "$logfilename" "$rollfilename"`;
|
|
#unlink($dirname);
|
|
}
|
|
$confirmMessage = $messages{'ErrorLogResetConf'};
|
|
}
|
|
|
|
sub SaveBroadcasterSettings {
|
|
my $restartBroadcaster = 0;
|
|
my $changedNetworkSetting = 0;
|
|
my %messages = %$messageHash;
|
|
|
|
if (!$broadcasterConn) {
|
|
RestartBroadcaster();
|
|
if (!$broadcasterConn) {
|
|
$filename = 'start_broadcaster.html';
|
|
return false;
|
|
}
|
|
}
|
|
|
|
if (($broadcasterConn->state != 0) && ($theAction eq 'SaveBroadcasterSettings')) {
|
|
$restartBroadcaster = 1;
|
|
$broadcasterConn->stopBroadcast;
|
|
}
|
|
if ($query->{'qtbCurrentAudioPreset'} ne $query->{'qtbCurrentAudioPreset_shadow'}) {
|
|
$changedNetworkSetting = 1;
|
|
&broadcasterlib::SetCurrentPresetForType($broadcasterConn, 0, $query->{'qtbCurrentAudioPreset'});
|
|
}
|
|
if ($query->{'qtbCurrentVideoPreset'} ne $query->{'qtbCurrentVideoPreset_shadow'}) {
|
|
$changedNetworkSetting = 1;
|
|
&broadcasterlib::SetCurrentPresetForType($broadcasterConn, 1, $query->{'qtbCurrentVideoPreset'});
|
|
}
|
|
if ($query->{'qtbAudioStreamEnabled'} ne $query->{'qtbAudioStreamEnabled_shadow'}) {
|
|
&broadcasterlib::SetStreamEnabledForType($broadcasterConn, 0, $query->{'qtbAudioStreamEnabled'});
|
|
}
|
|
if ($query->{'qtbVideoStreamEnabled'} ne $query->{'qtbVideoStreamEnabled_shadow'}) {
|
|
&broadcasterlib::SetStreamEnabledForType($broadcasterConn, 1, $query->{'qtbVideoStreamEnabled'});
|
|
}
|
|
if ($query->{'qtbRecordingPath'} ne $query->{'qtbRecordingPath_shadow'}) {
|
|
&broadcasterlib::SetRecordingPath($broadcasterConn, $query->{'qtbRecordingPath'});
|
|
}
|
|
if ($query->{'qtbNetworkPresetSDPFilename'} ne $query->{'qtbNetworkPresetSDPFilename_shadow'}) {
|
|
$changedNetworkSetting = 1;
|
|
&broadcasterlib::SetNetworkFilepath($query->{'qtbNetworkPresetSDPFilename'});
|
|
}
|
|
if ($query->{'qtbBufferDelay'} ne $query->{'qtbBufferDelay_shadow'}) {
|
|
$changedNetworkSetting = 1;
|
|
&broadcasterlib::SetBufferDelay($query->{'qtbBufferDelay'});
|
|
}
|
|
if ($changedNetworkSetting == 1) {
|
|
&broadcasterlib::RereadSettingsFile($broadcasterConn);
|
|
}
|
|
if (($restartBroadcaster) && ($theAction eq 'SaveBroadcasterSettings')) {
|
|
StartStopBroadcast();
|
|
}
|
|
if ($confirmMessage ne $messages{'QTBErrBroadcastSettings'}) {
|
|
$confirmMessage = $messages{'QTBConfSaved'};
|
|
}
|
|
}
|
|
|
|
sub StartStopBroadcast {
|
|
if ($theAction eq 'StartStopBroadcast') {
|
|
SaveBroadcasterSettings();
|
|
}
|
|
my %messages = %$messageHash;
|
|
my $messageName = '';
|
|
if ($broadcasterConn) {
|
|
$messageName = &broadcasterlib::StartStopBroadcast($broadcasterConn);
|
|
}
|
|
$confirmMessage = $messages{$messageName};
|
|
if ($messageName eq '') { # couldn't start broadcast
|
|
$confirmMessage = $messages{'QTBErrBroadcastSettings'};
|
|
}
|
|
if ($messageName eq 'QTBConfStarted') {
|
|
my $value = '/modules/admin/server/qtssSvrDefaultDNSName';
|
|
my $data = '';
|
|
my $status = adminprotolib::EchoData($data, $messHash, $authheader, $qtssip, $qtssport, $value, $value);
|
|
&broadcasterlib::WriteRefMovie($data);
|
|
my $cycles = 0;
|
|
my $continue = 1;
|
|
my $state;
|
|
while ($continue == 1) {
|
|
sleep(1);
|
|
$state = &broadcasterlib::GetBroadcasterStateID($broadcasterConn);
|
|
$cycles = $cycles + 1;
|
|
if (($cycles > 7) || ($state == 3)) {
|
|
$continue = 0;
|
|
}
|
|
}
|
|
if ($state != 3) {
|
|
$confirmMessage = $messages{'QTBErrBroadcastSettings'};
|
|
}
|
|
}
|
|
}
|
|
|
|
sub RestartBroadcaster {
|
|
eval("require 'broadcaster_lib.pl';");
|
|
&broadcasterlib::KillServer(1);
|
|
sleep(1);
|
|
ConnectToBroadcaster(1);
|
|
}
|
|
|
|
|
|
# this routine performs an action, if there is any
|
|
sub PerformAction {
|
|
my $messHash = adminprotolib::GetMessageHash();
|
|
my %messages = %$messHash;
|
|
if ($theAction eq 'refreshmessages') {
|
|
# refresh the message hashes from the correct files.
|
|
&streamingadminserver::LoadMessageHashes();
|
|
}
|
|
elsif ($theAction eq 'login') {
|
|
$cookie = 'qtsspassword='.encodeBase64($query->{'qtssusername'}.':'.$query->{'qtsspassword'}).'; path=/';
|
|
return true;
|
|
}
|
|
elsif ($theAction eq 'logout') {
|
|
$cookie = 'qtsspassword=; path=/';
|
|
return true;
|
|
}
|
|
elsif ($theAction eq 'StartStopServer') {
|
|
StartStopServer();
|
|
}
|
|
elsif ($theAction eq 'restartadminserver') {
|
|
restart_streamingadminserver();
|
|
return true;
|
|
}
|
|
elsif ($theAction eq 'setrefresh') {
|
|
if (getCookie('pageRefreshInterval') ne $query->{'pageRefreshInterval'}) {
|
|
$cookie = 'pageRefreshInterval='.$query->{'pageRefreshInterval'}.'; path=/';
|
|
}
|
|
else {
|
|
$cookie = 'displayCount='.$query->{'displayCount'}.'; path=/';
|
|
}
|
|
return true;
|
|
}
|
|
elsif ($theAction eq 'setconnusersort') {
|
|
$cookie = 'connUserSort='.$query->{'connUserSort'};
|
|
}
|
|
elsif ($theAction eq 'setrelaystatsort') {
|
|
$cookie = 'relayStatSort='.$query->{'relayStatSort'};
|
|
}
|
|
elsif ($theAction eq 'SaveGeneralSettings') {
|
|
SaveGeneralSettings();
|
|
}
|
|
elsif ($theAction eq 'ChangePassword') {
|
|
ChangePassword();
|
|
}
|
|
elsif ($theAction eq 'ConfirmPassChanged') {
|
|
$confirmMessage = $messages{'ChPassSavedText'};
|
|
}
|
|
elsif ($theAction eq 'ChangeMP3Password') {
|
|
ChangeMP3Password();
|
|
}
|
|
elsif ($theAction eq 'ChangeBroadcastPassword') {
|
|
ChangeBroadcastPassword();
|
|
}
|
|
elsif ($theAction eq 'SaveLogSettings') {
|
|
SaveLogSettings();
|
|
}
|
|
elsif ($theAction eq 'SavePortSettings') {
|
|
SavePortSettings();
|
|
}
|
|
elsif ($theAction eq 'StartPlaylist') {
|
|
StartPlaylist();
|
|
}
|
|
elsif ($theAction eq 'StopPlaylist') {
|
|
StopPlaylist();
|
|
}
|
|
elsif ($theAction eq 'ShowPlaylistLog') {
|
|
ShowPlaylistLog();
|
|
}
|
|
elsif ($theAction eq 'GetPlaylist') {
|
|
GetPlaylist();
|
|
}
|
|
elsif ($theAction eq 'CreatePlaylist') {
|
|
CreatePlaylist();
|
|
}
|
|
elsif ($theAction eq 'NewMP3Playlist') {
|
|
$isMP3 = 1;
|
|
NewPlaylist();
|
|
}
|
|
elsif ($theAction eq 'NewMoviePlaylist') {
|
|
$isMP3 = 0;
|
|
NewPlaylist();
|
|
}
|
|
elsif ($theAction eq 'RefreshPlaylistDir') {
|
|
RefreshPlaylistDir();
|
|
}
|
|
elsif ($theAction eq 'DeletePlaylist') {
|
|
DeletePlaylist();
|
|
}
|
|
elsif ($theAction eq 'getValsForRelay') {
|
|
getValsForRelay();
|
|
}
|
|
elsif ($theAction eq 'getNewRelay') {
|
|
getNewRelay();
|
|
}
|
|
elsif ($theAction eq 'getRelayDestData') {
|
|
getRelayDestData();
|
|
}
|
|
elsif ($theAction eq 'SetRelayDestData') {
|
|
SetRelayDestData();
|
|
}
|
|
elsif ($theAction eq 'AddRelayDestination') {
|
|
AddRelayDestination();
|
|
}
|
|
elsif ($theAction eq 'DeleteRelayDest') {
|
|
DeleteRelayDest();
|
|
}
|
|
elsif ($theAction eq 'SaveRelay') {
|
|
SaveRelay();
|
|
}
|
|
elsif ($theAction eq 'DeleteRelay') {
|
|
DeleteRelay();
|
|
$confirmMessage = $messages{'RelayDeleteText'};
|
|
}
|
|
elsif ($theAction eq 'RunAssistant') {
|
|
RunAssistant();
|
|
if (-e "index.html") {
|
|
unlink("index.html");
|
|
}
|
|
}
|
|
elsif ($theAction eq 'AssistSetPassword') {
|
|
my $setupAssistantPasswordSuccess = AssistSetPassword();
|
|
if (($setupAssistantPasswordSuccess == 1) && (-e "index.html")) {
|
|
unlink("index.html");
|
|
}
|
|
}
|
|
elsif ($theAction eq 'ResetErrorLog') {
|
|
ResetErrorLog();
|
|
}
|
|
elsif ($theAction eq 'SaveBroadcasterSettings') {
|
|
SaveBroadcasterSettings();
|
|
}
|
|
elsif ($theAction eq 'StartStopBroadcast') {
|
|
StartStopBroadcast();
|
|
}
|
|
elsif ($theAction eq 'StartBroadcaster') {
|
|
eval("require 'broadcaster_lib.pl';");
|
|
ConnectToBroadcaster(1);
|
|
sleep(3);
|
|
}
|
|
elsif ($theAction eq 'RestartBroadcaster') {
|
|
RestartBroadcaster();
|
|
}
|
|
elsif ($theAction eq 'QuitBroadcaster') {
|
|
eval("require 'broadcaster_lib.pl';");
|
|
ConnectToBroadcaster(0);
|
|
if (!(!$broadcasterConn || !$$broadcasterConn)) {
|
|
&broadcasterlib::QuitBroadcaster($broadcasterConn);
|
|
}
|
|
my %messages = %$messageHash;
|
|
$confirmMessage = $messages{'QTBConfQuit'};
|
|
}
|
|
elsif ($theAction eq '') {
|
|
return true;
|
|
}
|
|
else {
|
|
die("Action not found!");
|
|
}
|
|
}
|
|
|
|
# post method environment variable
|
|
$cl = $ENV{"CONTENT_LENGTH"};
|
|
|
|
if ($ENV{"REQUEST_METHOD"} eq "POST")
|
|
{
|
|
# put the data into a variable
|
|
read(STDIN, $qs, $cl);
|
|
$query = &adminprotolib::ParseQueryString($qs);
|
|
}
|
|
elsif ($ENV{"REQUEST_METHOD"} eq "GET")
|
|
{
|
|
$qs = $ENV{"QUERY_STRING"};
|
|
$query = &adminprotolib::ParseQueryString($qs);
|
|
}
|
|
|
|
# get the filename
|
|
$filename = $query->{'filename'};
|
|
if (($filename =~ /[^A-Za-z0-9_\-\.\/]/) or ($filename =~ /\.{2,}/) or ($filename =~ /\/{2,}/)) {
|
|
die "Can't access HTML file!";
|
|
}
|
|
$auth = $query->{'qtsspassword'};
|
|
$username = $query->{'qtssusername'};
|
|
$cookie = $query->{'cookie'};
|
|
$confirmMessage = '';
|
|
$chdelim = &playlistlib::GetFileDelimChar();
|
|
$serverRoot = $ENV{"SERVER_ROOT"};
|
|
|
|
# fix for 3148849
|
|
# if the filename starts with /, remove the slash
|
|
$filename =~ s/^\///;
|
|
|
|
# fix for 3064725
|
|
# if the setup assistant is being called and the index file no longer exists,
|
|
# clear $filename so we get the frameset instead
|
|
if (($filename =~ m/setup_assistant2/) && (!(-e "$serverRoot/index.html")))
|
|
{
|
|
$filename = '';
|
|
}
|
|
|
|
# new auth code
|
|
if ($auth eq '') {
|
|
#if ($cookies{'qtsspassword'}) {
|
|
# $auth = $cookies{'qtsspassword'}->value;
|
|
#}
|
|
# can't use CGI library; parsing by hand
|
|
if (getCookie('qtsspassword')) {
|
|
$auth = getCookie('qtsspassword');
|
|
}
|
|
}
|
|
else {
|
|
$auth = encodeBase64("$username:$auth");
|
|
}
|
|
$authheader = "Authorization: Basic $auth\r\n";
|
|
$theAction = $query->{'action'};
|
|
$wasAuth = 1;
|
|
|
|
# fake a found tag to force authentication before performing an action
|
|
if (($theAction ne '') && !($nonAuthenticatedActions =~ m/\|$theAction\|/o)) {
|
|
foundTag(' name="qtssSvrDefaultDNSName"', '', '/');
|
|
|
|
if ($wasAuth <= 0) {
|
|
undef($query);
|
|
undef($qs);
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
# run the action if there is one
|
|
PerformAction();
|
|
|
|
# hack for QT Broadcaster library on Mac OS X Only
|
|
if ($filename eq 'broadcaster_settings.html') {
|
|
if (!(-e '/Applications/QuickTime Broadcaster.app')) {
|
|
my %messages = %$messageHash;
|
|
$confirmMessage = $messages{'QTBErrNotInstalledText'};
|
|
$filename = 'welcome.html';
|
|
}
|
|
else {
|
|
my $result = ConnectToBroadcaster(0);
|
|
if ($result == 0) { # couldn't connect to broadcaster
|
|
$filename = 'start_broadcaster.html';
|
|
}
|
|
elsif ($result == (-1)) {
|
|
$filename = 'restart_broadcaster.html';
|
|
}
|
|
}
|
|
}
|
|
|
|
if ($confirmMessage ne '') { # if we're confirming a save, then do a redirect from the post operation.
|
|
if ($confirmMessage eq 'redirect') {
|
|
$confirmMessage = '';
|
|
}
|
|
else {
|
|
$confirmMessage =~ s/\s/%20/g;
|
|
$confirmMessage =~ s/&/%26/g;
|
|
}
|
|
&cgilib::PrintRedirectHeader($ENV{"SERVER_SOFTWARE"}, "/parse_xml.cgi?filename=$filename&confirmMessage=$confirmMessage");
|
|
return 0;
|
|
}
|
|
|
|
else {
|
|
|
|
$confirmMessage = $query->{'confirmMessage'};
|
|
|
|
chdir($ENV{"SERVER_ROOT"});
|
|
|
|
# default here
|
|
if (($filename eq '') or (($filename eq 'login.html') and ($query->{'action'} eq 'login'))) {
|
|
$filename = "frameset.html";
|
|
}
|
|
if ($templatefile eq '') {
|
|
$templatefile = "template.html";
|
|
}
|
|
|
|
#prevent source code revelation
|
|
if (!($filename =~ m/\.html$/)) {
|
|
die "Can't access HTML file '$filename'!";
|
|
}
|
|
|
|
#prevent windows ports from being opened
|
|
#aux, con, prn, com*, lpt?, nul
|
|
$foundFilename = 0;
|
|
opendir(FILEDIR, $ENV{"SERVER_ROOT"}) or die "Can't access HTML file '$filename'!";
|
|
while (defined($subpath = readdir(FILEDIR))) {
|
|
$foundFilename = 1 if $subpath eq $filename;
|
|
}
|
|
die "Can't access HTML file '$filename'!" if $foundFilename == 0;
|
|
|
|
$text = '';
|
|
$templatetext = '';
|
|
|
|
if (!(-e "$filename")) {
|
|
die "Can't access HTML file '$filename'!";
|
|
}
|
|
|
|
open(HTMLFILE, $filename) or die "Can't open HTML file '$filename'!";
|
|
|
|
# read the entire file into
|
|
|
|
while ($line = <HTMLFILE>) {
|
|
$text .= $line;
|
|
}
|
|
|
|
# we're done with the file; now close it
|
|
close(HTMLFILE);
|
|
|
|
# if the template contains the <bodytext/> tag, replace it with the body text from the file
|
|
if ($templatetext =~ /<bodytext\/>/gix) {
|
|
$templatetext =~ s/<bodytext\/>/$text/gix;
|
|
$text = $templatetext;
|
|
}
|
|
|
|
# parse the tags in the file's text
|
|
$text = parseTags($text);
|
|
|
|
if ($wasAuth <= 0) {
|
|
undef($query);
|
|
undef($qs);
|
|
return 0;
|
|
}
|
|
|
|
# used to be makeSecureRoot()
|
|
if ($^O ne "MSWin32") {
|
|
chroot($ENV{"SERVER_ROOT"});
|
|
die "Can't open HTML file '$filename!'" if (!(-e $ENV{"SERVER_ROOT"}.'/'.$filename));
|
|
}
|
|
if (($^O eq "MSWin32") && &adminprotolib::CheckIfForbidden($ENV{"SERVER_ROOT"}, $filename)) {
|
|
die "Can't open HTML file '$filename'!";
|
|
}
|
|
|
|
open(HTMLFILE, $filename) or die "Can't open HTML file '$filename'!";
|
|
close(HTMLFILE);
|
|
|
|
# give them a new cookie unless we have a better plan for them
|
|
if ($cookie eq '') {
|
|
$cookie = 'qtsspassword='.getCookie('qtsspassword').'; path=/';
|
|
}
|
|
|
|
# CGI programs must print their own HTTP response headers
|
|
&cgilib::PrintOKTextHeader($servername, $cookie);
|
|
|
|
#print the replaced HTML
|
|
print $text;
|
|
|
|
}
|
|
|
|
# done!
|
|
undef($query);
|
|
undef($qs);
|
|
return 0;
|