#!/usr/bin/env perl # MP3 FreeRADIO song selection server, v1.2 ## Start user config # # connection log file $log = "/skratch/log"; # current playing song file $play = "/skratch/play"; # user selection request $usel = "/skratch/usersel"; # lock for server $lock = "/skratch/serverlock"; # songlist file $list = "/home/list/.plan"; # mp3 count file $cfile = "/skratch/.count"; # url for info/songlist $url = "http://127.0.0.1"; # port to sit on $port = 31337; # ## End user config use Socket; use FileHandle; sub spawn; unlink $lock; # SysV argv thing. Comment out if it annoys you # $argv = "mp3radio.server"; for ($i = 1; $i < 80; $i++) { $argv = $argv . "\000"; } $0 = $argv; open C, $cfile || die "Can't open $cfile: $!\n"; $count = ; open C, $list || die "Can't open $list: $!\n"; @list = ; close C; sub Help { print "\nCommands: \n\n". " enter - Enter song selection menu. \n". " help - Prints this. \n". " playing - Show currently playing song. \n". " check - Check for a song (given song name, artist or number)\n". " quit - Leave the joint. \n\n". "That's it. \n". "See $url for more info and a songlist. \n\n". "-> "; } ($name, $aliases, $protocol) = getprotobyname('tcp'); socket(S, PF_INET, SOCK_STREAM, $protocol) || die "socket: $!"; setsockopt(S, SOL_SOCKET, SO_REUSEADDR, pack("l", 1)) || die "setsockopt: $!"; bind(S, sockaddr_in ($port, INADDR_ANY)) || die "bind: $!"; listen(S, SOMAXCONN) || die "listen: $!"; $paddr = 0; $iaddr = 0; $name = 0; $_ = 0; @_ = (0); $coderef = 0; $pid = 0; $waitedpid = 0; $port = 0; sub ABDUCTOR { $waitedpid = wait; $SIG{CHLD} = \&ABDUCTOR; } $SIG{CHLD} = \&ABDUCTOR; for (; $paddr = accept(Client, S); close Client) { ($port, $iaddr) = sockaddr_in($paddr); $name = gethostbyaddr($iaddr, AF_INET); open LOG, ">>$log" || warn "\nCan't open $log: $!\n\n"; print LOG "\n", scalar gmtime, "\n". "Connection from $name [", inet_ntoa($iaddr); print LOG "] at port $port\n"; close LOG; spawn sub { print "\n\n\t\t\tWelcome to MP3 FreeRADIO\n\n\n". "Type 'help' for some help.\n\n\n". "-> "; while (($_ = ) && ($_ !~ /^(quit|exit)/i)) { if (/^(enter|ent\w*)/i) { if (-z $lock) { print "\nThe system is currently in use. Please try again later.\n\n"; exit 1; } print "\n"; while (!$sel || $sel > $count) { print "Enter a song selection number: "; chomp($sel = ); $sel =~ tr/0-9//csd; } $sel =~ s/[\r\n]//g; open F, ">$usel" || die "Can't create $usel: $!\n"; print F $sel; open F, ">$lock" || die "Can't create $lock: $!\n"; close F; foreach (@list) { if (/^$sel/) { print "\nYour selection:\n\n". "$_". "\nThank You.\n\n"; last; } } exit 0; } elsif (/^(help|h\w*|\?)/i) { &Help; } elsif (/^(playing|play|p\w*)/i) { if (-T $play) { open PLAY, $play || warn "Can't open $play: $!\n"; while () { print; } close PLAY; } else { print "No current playing song\n"; } print "-> "; } elsif (/^(check|che\w*)/i) { print "\n"; while (!$chk) { print "Enter a piece of song information: "; chomp($chk = ); $chk =~ s/[\r\n]//g; } print "\nMatches:\n\n"; foreach (@list) { if (/$chk/i) { print; } } undef $chk; print "\n-> "; } else { &Help; } } print "\nLeaving...\n\n"; }; } sub spawn { local($coderef, $pid); $coderef = shift; @_ = (); $_ = ""; if (!defined ($pid = fork)) { return; } elsif ($pid) { return; } open STDIN, "<&Client" || die "Can't dup client to stdin\n"; open STDOUT, ">&Client" || die "Can't dup client to stdout\n"; STDOUT->autoflush(); exit &$coderef(); }