#!/usr/bin/perl

# vi: sw=4 ts=4

use strict;
use warnings;

use XML::Parser;

our $VERSION = 0.01;

my $NAMESPACE = 'http://purl.org/NET/webdav/mount';

my $url;
my $open;

my $parser = new XML::Parser(Handlers => {Start => \&handle_start,
       End => \&handle_end,
       Char => \&handle_char}, Namespaces => 1);

$parser->parsefile(shift);
$open = $open || '';

my $client = shift || 'cadaver';

exec $client, $url . $open;

sub handle_start {
       my ($parser, $name, $attrs) = @_;

       if ($parser->namespace($name) ne $NAMESPACE) {
               $parser->xpcarp("invalid davmount syntax");
       }

       if (defined $attrs) {
               $parser->xpcarp("invalid davmount syntax");
       }

       my @context = $parser->context;
       my $context = pop @context;

       if (!defined $context) {
               if ($name eq 'mount') {
                       return;
               }

               $parser->xpcarp("invalid davmount syntax");
       }

       if ($context eq 'mount') {
               if ($name eq 'url' && !defined $url) {
                       $url = '';
                       return;
               }

               if ($name eq 'open' && !defined $open) {
                       $open = '';
                       return;
               }

               if ($name eq 'user') {
                       return;
               }

               $parser->xpcarp("invalid davmount syntax");
       }

       $parser->xpcarp("invalid davmount syntax");
}

sub handle_end {
       my ($parser, $name) = @_;

       if ($parser->namespace($name) ne $NAMESPACE) {
               $parser->xpcarp("invalid davmount syntax");
       }

       my @context = $parser->context;
       my $context = pop @context;

       if (!defined $context) {
               if ($name eq 'mount') {
                       $parser->finish;
                       return;
               }

               $parser->xpcarp("invalid davmount syntax");
       }

       if ($context eq 'mount') {
               if ($name eq 'url' && defined $url) {
                       return;
               }

               if ($name eq 'open' && defined $open) {
                       return;
               }

               if ($name eq 'user') {
                       return;
               }

               $parser->xpcarp("invalid davmount syntax");
       }

       $parser->xpcarp("invalid davmount syntax");
}

sub handle_char {
       my ($parser, $string) = @_;

       my @context = $parser->context;
       my $context = pop @context;

       # Whitespace in <dm:mount></dm:mount> isn't invalid syntax
       if ($context eq 'mount' && $string =~ /\s+/) {
               return;
       }

       if ($context eq 'url') {
               $url .= $string;
               return;
       }

       if ($context eq 'open') {
               $open .= $string;
               return;
       }

       if ($context eq 'user') {
               return;
       }

       $parser->xpcarp("invalid davmount syntax");
}

__END__

=head1 NAME

davmount -- parse davmount file & mount described WebDAV resource

=head1 SYNOPSIS

davmount file [client]

=head1 OPTIONS

=over 8

=item B<file>

davmount file

=item B<client>

WebDAV client with which to mount described WebDAV resource.  Default: 'cadaver'

=back

=head1 PREREQUISITES

XML::Parser

=head1 SCRIPT CATEGORIES

Web

=head1 SEE ALSO

L<http://greenbytes.de/tech/webdav/draft-reschke-webdav-mount-latest.html>