]> git.draconx.ca Git - mpdhacks.git/blobdiff - MPDHacks.pm
Factor out MPD connection code.
[mpdhacks.git] / MPDHacks.pm
index 2c76c2f703c54621423741ad05e4a1dcdbd6cb1d..94c0acc518dbad5067eb1c4456c4877ee169955d 100644 (file)
@@ -13,10 +13,81 @@ use strict;
 use Exporter;
 our ($VERSION, @ISA, @EXPORT);
 
+use IO::Socket::INET6;
+use IO::Socket::UNIX;
+
 $VERSION = 0;
 @ISA = qw(Exporter);
 @EXPORT = qw();
 
+our $host = $ENV{MPD_HOST} // "localhost";
+our $port = $ENV{MPD_PORT} // 6600;
+our $sock;
+
+our ($major, $minor, $revision);
+
+# MPD::connect([ARGS])
+#
+# Connect to MPD based on the current settings of $MPD::host and $MPD::port.
+#
+# The following key-value arguments may optionally be specified:
+#
+#   binmode => socket binmode, e.g., :utf8 or :raw.  The default is :utf8.
+#
+#              Text in the MPD protocol is always UTF-8 encoded but some
+#              commands return raw binary data which can be easier to
+#              handle in :raw mode.
+#
+# On failure, an error message is printed and undef is returned.
+sub connect {
+       my %args = @_;
+
+       if ($host =~ /^[@\/]/) {
+               $host =~ s/^@/\0/;
+               $sock = new IO::Socket::UNIX(Type => SOCK_STREAM(),
+                                            Peer => $host)
+       } else {
+               $sock = new IO::Socket::INET6(PeerAddr => $host,
+                                             PeerPort => $port,
+                                             Proto    => 'tcp',
+                                             Timeout  => 2)
+       }
+       die "MPD connection failed: $!\n" unless $sock;
+
+       binmode($sock, $args{binmode} // ":utf8");
+       unless (<$sock> =~ /^OK MPD ([0-9]+)\.([0-9]+)\.([0-9]+)$/) {
+               $sock->close();
+               die "MPD failed to announce version: $!\n";
+       }
+
+       ($major, $minor, $revision) = ($1, $2, $3);
+       return $sock;
+}
+
+# min_version(x, y, z)
+#
+# Returns true iff the MPD protocol version is at least x.y.z.
+sub min_version {
+       my ($maj, $min, $rev) = @_;
+
+       if (defined $maj) {
+               return 1 if $maj < $major;
+               return 0 if $maj > $major;
+       }
+
+       if (defined $min) {
+               return 1 if $min < $minor;
+               return 0 if $min > $minor;
+       }
+
+       if (defined $rev) {
+               return 1 if $rev < $revision;
+               return 0 if $rev > $revision;
+       }
+
+       return 1;
+}
+
 # Returns the argument (or $_ if no arguments are supplied) quoted so that it
 # can be presented as a single command argument to MPD at the protocol level.
 sub escape {