perl: Integrate the mup interface from https://github.com/StAlphonsos/mup

This commit is contained in:
attila 2016-08-26 15:28:03 -05:00
parent 2507933176
commit 6b366e7d25
22 changed files with 2287 additions and 5 deletions

View File

@ -28,7 +28,13 @@ else
mu4e=
endif
SUBDIRS=m4 man lib $(guile) mu $(mu4e) contrib toys
if BUILD_PERL
perl=perl
else
perl=
endif
SUBDIRS=m4 man lib $(guile) mu $(mu4e) contrib toys $(perl)
ACLOCAL_AMFLAGS=-I m4

View File

@ -70,6 +70,20 @@ AS_IF([test "x$enable_mu4e" != "xno"], [
])
AM_CONDITIONAL(BUILD_MU4E, test "x$build_mu4e" = "xyes")
# Perl interface requires Data::SExpression
build_perl=no
AC_ARG_ENABLE([perl],
AS_HELP_STRING([--enable-perl],[Enable building the Perl interface]))
AC_ARG_VAR([PERL], [the Perl interpreter command])
AC_CHECK_PROGS([PERL], [perl], [no])
AS_IF([test x"$enable_perl" != "xno" -a x"$PERL" != "xno"], [
AM_PERL_MODULE([Data::SExpression],[build_perl=yes])
if test x"$build_perl" = "xyes"; then
perl_version=`$PERL -Iperl/lib -Mmup -e 'print "$mup::VERSION\n";'`
fi
])
AM_CONDITIONAL(BUILD_PERL, test "x$build_perl" = "xyes")
# we need some special tricks for filesystems that don't have d_type;
# e.g. Solaris. See mu-maildir.c. Explicitly disabling it is for
# testing purposes only
@ -269,6 +283,13 @@ contrib/Makefile
])
AC_OUTPUT
if test x"$build_perl" != "xno"; then
echo "Configuring Perl interface..."
cd perl
$PERL Makefile.PL
cd ..
fi
echo
echo "mu configuration is complete."
echo "------------------------------------------------"
@ -299,6 +320,10 @@ if test "x$build_mu4e" = "xyes"; then
echo "Emacs version : $emacs_version"
fi
AM_COND_IF([BUILD_PERL],[
echo "Perl interface version : $perl_version"
])
echo
echo "Have wordexp : $ac_cv_header_wordexp_h"
echo "Build mu4e emacs frontend : $build_mu4e"
@ -308,7 +333,6 @@ echo "Build 'mug' toy-ui (gtk+/webkit) : yes"],[
echo "Build 'mug' toy-ui (gtk+/webkit) : no"
])
echo "McCabe's Cyclomatic Complexity tool : $have_pmccabe"
echo

View File

@ -21,6 +21,5 @@ EXTRA_DIST = \
ltoptions.m4 \
ltversion.m4 \
lt~obsolete.m4 \
ltsugar.m4
ltsugar.m4 \
perlmod.m4

15
perl/LICENSE Normal file
View File

@ -0,0 +1,15 @@
Copyright (C) 2015 by attila <attila@stalphonsos.com>
Permission to use, copy, modify, and distribute this software for
any purpose with or without fee is hereby granted, provided that the
above copyright notice and this permission notice appear in all
copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.

19
perl/MANIFEST Normal file
View File

@ -0,0 +1,19 @@
lib/mup.pm
LICENSE
Makefile.PL
MANIFEST This list of files
README.md
t/001-basics.t
t/002-index.t
t/003-contacts.t
t/004-add.t
t/005-find.t
t/006-move.t
t/007-remove.t
t/008-view.t
t/009-extract.t
t/010-compose.t
t/lib.pm
t/sample.eml
t/sample.maildir/cur/1435599858.6310_1.tldr.l.stalphonsos.net
t/sample.maildir/new/1416411736.20539_44.geronimo.l.stalphonsos.net

31
perl/Makefile.PL Normal file
View File

@ -0,0 +1,31 @@
# mu - perl interface to mu
use ExtUtils::MakeMaker;
do "./lib/mup.pm";
sub SRC { "lib/@_" }
sub DST { '$(INST_LIBDIR)/'."@_" }
sub PAIR { ( SRC(@_) => DST(@_) ) }
print STDERR "Welcome to mup $mup::VERSION\n\n";
WriteMakefile(
AUTHOR => 'attila <attila@stalphonsos.com>',
ABSTRACT => 'perl interface to mu',
NAME => 'mup',
VERSION_FROM => 'lib/mup.pm',
PREREQ_PM => {
'Data::SExpression' => 0,
'Moose' => 0,
},
PM => {
PAIR('mup.pm'),
}
);
sub MY::postamble {
return <<__MyStuff__;
check:
__MyStuff__
}

31
perl/README.md Normal file
View File

@ -0,0 +1,31 @@
# mup #
mup is a perl interface to [mu](http://www.djcbsoftware.nl/code/mu/)
([GitHub](https://github.com/djcb/mu)), a Maildir indexing and
search system that also implements the core functionality needed
by pretty much any MUA.
mup replicates the API described in the
[mu-server(1)](http://manpages.ubuntu.com/manpages/precise/man1/mu-server.1.html) man page in a pleasingly Perly style. It is licensed under the
[ISC license](http://en.wikipedia.org/ISC_licnse), a simplified
variant of the [BSD license](http://en.wikipedia.org/BSD_licenses).
mup works in the same way the elisp code in mu4e does: it forks
a `mu-server` process and communicates with it. I use the
[Data::SExpression](http://search.cpan.org/~nelhage/Data-SExpression-0.41/lib/Data/SExpression.pm) CPAN module to deal with `mu-server`'s LISPy result syntax,
which we transform into the obvious hashrefian results our callers crave
(they've got electrolytes).
## Tests ##
I use standard perl testing stuff (`Test::More`). The tests all
operate on a temporary Maildir/mu index created by `t/lib.pm`. If you
are interested in hacking on or understanding the tests you should
first look at `t/lib.pm` to see how the temporary setup is created and
torn down. All tests should have
use t::lib;
in them somewhere near the top. This is all that is necessary to make
sure the code in the test does not e.g. hose down your actual
~/Maildir and/or ~/.mu.

863
perl/lib/mup.pm Normal file
View File

@ -0,0 +1,863 @@
#! perl
=pod
=head1 NAME
mup - perl interface to mu
=head1 SYNOPSIS
use mup;
my $mu = mup->new();
my $results = $mu->find({ subject => 'something'});
print "$results->{found} results for subject:something\n";
=head1 DESCRIPTION
This is a perl interface to mu, the Maildir search-and-destroy system.
It presents the same API as described in the L<mu-server(1)> man page.
In fact it works by communicating with a C<mu server> process, just
like the C<mu4e> emacs interface to mu does.
=head1 METHODS
All of the following methods take arguments named as described in the
L<mu-server(1)> man page per each command, again either as a single
hashref argument or as a hash of pairs in-line. If there are any
doubts, make sure to read the L<mu-server(1)> man page. Where
relevant any C<maildir> argument defaults to C<~/Maildir> (not our
doing, that's just how C<mu> rolls).
In order to stay agnostic with respect to the use our clients put us
to, all exported methods return plain, unblessed hashrefs as their
result. The shape of this hashref corresponds to the S-Expression
described in the L<mu-server(1)> man page for each command. Since
everything that comes back from the server is represented as a list
(to us: array), we use a simple heuristic to determine if a an array
in the output is hashrefian or not: if it is of non-zero, even length
and if every even-numbered key is a symbol that starts with a colon we
consider the array hashrefian. In these cases we perform the obvious
transformation of stripping the leading colon and turning the thing
into a hashref.
=cut
package mup;
use strict;
use warnings;
use vars qw($VERSION);
use Data::SExpression;
use IO::Select;
use IPC::Open2;
use Moose;
use Time::HiRes;
use Data::Dumper;
$VERSION = '0.1.0';
has 'dying' => (
is => 'rw',
isa => 'Bool',
required => 1,
default => 0
);
has 'dead' => (
is => 'rw',
isa => 'Bool',
required => 1,
default => 0
);
has 'pid' => (
is => 'rw',
isa => 'Int',
required => 1,
default => 0
);
has 'in' => (
is => 'rw'
);
has 'out' => (
is => 'rw'
);
has 'tout' => (
is => 'rw',
isa => 'Num',
default => 0.5,
required => 1,
);
has 'orig_tout' => (
is => 'rw',
isa => 'Num',
default => 0.5,
required => 1,
);
has 'select' => (
is => 'ro',
isa => 'Object',
default => sub { IO::Select->new() },
required => 1,
);
has 'inbuf' => (
is => 'rw',
isa => 'Str',
default => '',
required => 1,
);
has 'ds' => (
is => 'ro',
isa => 'Object',
default => sub {
Data::SExpression->new({ fold_alists => 1, use_symbol_class => 1})
},
required => 1,
);
has 'max_tries' => (
is => 'rw',
isa => 'Int',
default => 0,
required => 1,
);
has 'mu_bin' => (
is => 'rw',
isa => 'Str',
default => 'mu',
required => 1,
);
has 'mu_server_cmd' => (
is => 'rw',
isa => 'Str',
default => 'server',
required => 1,
);
has 'verbose' => (
is => 'rw',
isa => 'Bool',
default => 0,
required => 1,
);
has 'bufsiz' => (
is => 'rw',
isa => 'Int',
default => 2048,
required => 1,
);
has 'cur_cmd' => (
is => 'rw',
isa => 'Str',
default => '',
required => 1,
);
has 'maildir' => (
is => 'rw',
isa => 'Str',
default => $ENV{'MAILDIR'} || '',
required => 1,
);
has 'mu_home' => (
is => 'rw',
isa => 'Str',
default => '',
required => 1,
);
has 'debug' => (
is => 'rw',
isa => 'Bool',
default => 0,
required => 1,
);
has 'update_callback' => (
is => 'rw',
default => undef,
required => 0,
);
has 'no_updates' => (
is => 'rw',
isa => 'Bool',
default => 0,
required => 1,
);
sub _init {
my $self = shift(@_);
my($in,$out);
# The only way I know of to tell mu server what Maildir to use is
# the MAILDIR environment variable. If our caller specifies a
# maildir, set the envvar before we fork the server process.
if ($self->maildir) {
$ENV{'MAILDIR'} = $self->maildir;
warn("mup: setting MAILDIR=".$self->maildir."\n") if $self->verbose;
}
# Opposite logic here... a bit confusing: The testing code
# (c.f. t/lib.pm) wants to point us at a different .mu directory
# than the default (~/.mu); normally you don't want to do this
# but if we see a special envar ($MUP_MU_HOME) then set mu_home
# to this value - mu_home defaults to ''. In any event, if
# mu_home is set somehow, obey it, otherwise let mu use its
# default.
if ($ENV{'MUP_MU_HOME'}) {
$self->mu_home($ENV{'MUP_MU_HOME'});
warn("mup: set --muhome ".$self->mu_home."\n") if $self->verbose;
}
# Same for MUP_MU_BIN
if ($ENV{'MUP_MU_BIN'}) {
$self->mu_bin($ENV{'MUP_MU_BIN'});
warn("mup: set mu_bin to ".$self->mu_bin."\n") if $self->verbose;
}
my @cmdargs = ($self->mu_bin,$self->mu_server_cmd);
push(@cmdargs, "--muhome=".$self->mu_home) if $self->mu_home;
warn("mup: mu server cmd: @cmdargs\n") if $self->verbose;
my $pid = open2($out,$in,@cmdargs);
$self->orig_tout($self->tout);
$self->pid($pid);
$self->out($out);
$self->in($in);
$self->select->add($out);
my $junk = $self->_read();
warn("mup: _init junk: $junk\n") if $self->verbose;
return $self;
}
sub BUILD { shift->_init(); }
sub _cleanup {
my($self) = @_;
if ($self->pid) {
warn("mup: reaping mu server pid ".$self->pid."\n") if $self->verbose;
waitpid($self->pid,0);
$self->pid(0);
}
if ($self->inbuf) {
warn("mup: restart pitching inbuf: |".$self->inbuf."|\n")
if $self->verbose;
$self->inbuf('');
}
}
sub restart {
my($self) = @_;
$self->_cleanup();
}
sub reset {
my($self) = @_;
$self->_reset_parser();
return $self;
}
sub _read {
my($self) = @_;
my $restart_needed = 0;
my @ready = $self->select->can_read($self->tout);
while (@ready && !$restart_needed) {
foreach my $handle (@ready) {
my $buf = '';
my $nread = $handle->sysread($buf,$self->bufsiz);
if (!$nread) {
warn("mup: mu server died - restarting") if $self->verbose();
$restart_needed = 1;
} else {
$self->inbuf($self->inbuf . $buf);
warn("mup: <<< |$buf|\n") if $self->verbose;
}
}
@ready = $self->select->can_read($self->tout)
unless $restart_needed;
}
my $result = $self->inbuf;
$self->_cleanup() if ($self->dying || $restart_needed);
$self->_init() if $restart_needed && !$self->dying;
return $result;
}
sub _reset_parser {
}
sub _parse {
my($self,$in_update) = @_;
$in_update ||= $self->no_updates;
my($tries,$max_tries) = (0,$self->max_tries);
INCOMPLETE:
my $raw = $self->inbuf;
return undef unless $raw;
my($xcount,$left) = ($1,$2) if $raw =~ /^\376([\da-f]+)\377(.*)$/s;
my $count = hex($xcount);
my $nleft = length($left);
warn("mup: count=$count length=$nleft: |$left|\n")
if $self->verbose;
if ($count > $nleft) {
++$tries;
die("mup: FATAL: waiting for $count, tried $tries, only got $nleft")
if ($max_tries && $tries >= $max_tries);
warn("mup: short buffer, reading more ($tries)...\n")
if $self->verbose;
$self->_read();
goto INCOMPLETE;
}
chomp(my $sexp = substr($left,0,$count));
$self->inbuf(substr($left,$count));
my $data = $self->ds->read($sexp);
return undef unless defined($data);
warn("mup: parsed sexp: $data\n") if $self->verbose;
my $href = $self->_hashify($data);
if (!$in_update && $self->update_callback && $self->inbuf =~ /:update/) {
# We have an update callback. We have an update.
# Peanut butter, meet chocolate.
local $Data::Dumper::Terse = 1;
local $Data::Dumper::Indent = 0;
my $upd = $self->_parse(1);
warn("mup: update: ".Dumper($upd)."\n") if $self->verbose;
unless ($upd && exists($upd->{'update'})) {
die("mup: next msg was not pending update !? ".Dumper($upd)."\n");
}
&{$self->update_callback}($upd);
}
return $href;
}
# turn a LISPy keyword into a perlier hashref key
sub _delispify {
my $key = shift(@_);
$key = "$1" if "$key" =~ /^:(.*)$/;
$key =~ s/-/_/g;
return $key;
}
# turn a perly argument name into a lispy one
sub _lispify {
my $key = shift(@_);
$key =~ s/_/-/g;
return $key;
}
# _hashify - turn raw Data::SExpression result into canonical hashref
sub _hashify {
my($self,$thing) = @_;
my $rthing = ref($thing);
my $result = $thing;
warn("mup: rthing=$rthing: $thing\n") if $self->debug;
return $result unless $rthing;
if ($rthing eq 'Data::SExpression::Symbol') {
# nil is undef, t is 1, everything else becomes a string
if ($thing eq 'nil') {
$result = undef;
} elsif ($thing eq 't') {
$result = 1;
} else {
$result = "$thing";
}
} elsif ($rthing eq 'ARRAY') {
my $count = scalar(@$thing);
my $looks_hashrefian = $count && !($count & 1);
if ($looks_hashrefian) {
# Non-null array with even cardinality: check for hashrefian keys
my $i;
for ($i = 0; $i < $count; $i += 2) {
my $elt = $thing->[$i];
my $relt = ref($elt);
last if (($relt && $relt eq 'Data::SExpression::Symbol') &&
"$elt" !~ /^:/);
}
$looks_hashrefian = ($i < $count) ? 0 : 1;
if ($self->debug) {
local $Data::Dumper::Terse = 1;
local $Data::Dumper::Indent = 0;
warn("mup: looks_hashrefian=$looks_hashrefian: ".Dumper($thing)."\n");
}
}
if (!$looks_hashrefian) {
# just a plain old array
$result = [ map { $self->_hashify($_) } @$thing ];
} else {
# hashref in array's clothing
$result = {};
while (scalar(@$thing)) {
my($key,$val) = splice(@$thing,0,2);
$key = _delispify($key);
{ no strict 'vars';
warn("mup: ARRAY key=$key val=(".ref($val).") |$val|\n")
if $self->debug;
}
$result->{$key} = $self->_hashify($val);
}
}
} elsif ($rthing eq 'HASH') {
# xxx can this happen? Data::SExpression says so but mu will
# probably never send us one...
$result = {};
foreach my $key (keys(%$thing)) {
my $val = $thing->{$key};
$key = _delispify($key);
{ no strict 'vars';
warn("mup: HASH key=$key val=(".ref($val).") |$val|\n")
if $self->debug;
}
$result->{$key} = $self->_hashify($val);
}
}
return $result;
}
=pod
=over 4
=item * new (verbose => 1|0, ... other options... )
Construct a new interface object; this will cause a C<mu server>
process to be started.
Options can be specified Moose-style, either as a hashref
or as a hash of pairs:
=over 4
=item * verbose
If non-zero we spew debug output to C<stderr> via L<warn>.
=item * tout
Timeout in seconds for responses from L<mu-server(1)>. The
Can be fractional. The default is C<0.5> (500 msec).
=item * bufsiz
Buffer size for reads from the server. Default is 2048.
=item * max_tries
Max number of times we will try to read from the server to complete
a single transaction. By default this is zero, which means no limit.
=item * mu_bin
Name of the C<mu> binary to use to start the server.
=item * mu_server_cmd
C<Mu> subcommand used to start the server.
=item * mu_home
Directory for Mu to use to store the Xapian database and other
Mu-specific files. Defaults to C<~/.mu>.
=item * maildir
Root of the C<Maildir> tree that L<mu(1)> should operate on. Defaults
to whatever the C<$MAILDIR> environment variable is set to or
C<~/Maildir> if it is not set.
=item * debug
If non-zero additional debug output will be spewed via L<warn>, mainly
related to the transformation of L<Data::SExpression> objects into
hashrefs. This output is spewed independently of the value of C<verbose>.
=back
=back
=cut
=pod
=over 4
=item * finish
Shut down the mu server and clean up.
=back
=cut
sub finish {
my($self) = @_;
if ($self->pid) {
$self->dying(1);
$self->_send("cmd:quit");
my $junk = $self->_read();
warn("mup: trailing garbage in finish: |$junk|\n") if $self->verbose;
}
return 1;
}
sub DEMOLISH { shift->finish(); }
sub _refify {
my $href = ((@_ == 1) && (ref($_[0]) eq 'HASH')) ? $_[0] : { @_ };
return { map { _lispify($_) => $href->{$_} } keys(%$href) };
}
sub _quote {
my($val) = @_;
$val = qq|"$val"| if (!ref($val) && $val =~ /\s/);
$val;
}
sub _argify {
my $self = shift(@_);
my $href = _refify(@_);
if (exists($href->{'timeout'})) {
$self->tout($href->{'timeout'});
warn("mup: tout ".$self->orig_tout." => ".$self->tout."\n")
if $self->verbose;
delete($href->{'timeout'});
}
return join(' ', map { "$_:"._quote($href->{$_}) } keys(%$href));
}
sub _send {
my($self,$str) = @_;
$self->in->write("$str\n");
$self->in->flush();
return $self;
}
sub _execute {
my($self,$cmd,@args) = @_;
my $args = $self->_argify(@args);
my $cmdstr = "cmd:$cmd $args";
warn("mup: >>> $cmdstr\n") if $self->verbose;
if ($self->inbuf) {
my $junk = $self->inbuf;
warn("mup: pitching |$junk|\n") if $self->verbose;
}
$self->inbuf('');
$self->cur_cmd($cmd);
$self->_send($cmdstr);
$self->_read();
$self->tout($self->orig_tout);
return $self->_parse();
}
=pod
=over 4
=item * add (path => "/path/to/file", maildir => "/my/Maildir")
Add a message (document) to the database. If C<maildir> is not
specified the right thing is filled in.
=back
=cut
sub add {
my $self = shift(@_);
my $argref = _refify(@_);
$argref->{'maildir'} = $self->_our_maildir() unless $argref->{'maildir'};
$self->_execute('add',$argref);
}
=pod
=over 4
=item * compose (type => 'reply|forward|edit|new', docid => $docid)
Compose a message, either in regard to an existing one (in which case
you must specify C<docid>) or as a new message.
=back
=cut
sub compose { shift->_execute('compose',@_); }
=pod
=over 4
=item * contacts (personal => 1|0, after => $epoch_time)
Search contacts.
=back
=cut
sub contacts { shift->_execute('contacts',@_); }
=pod
=over 4
=item * extract (action => 'save|open|temp', index => $index, path => $path, what => $what, param => $param)
Save a message into a file.
=back
=cut
sub extract { shift->_execute('extract',@_); }
=pod
=over 4
=item * find (query => $mu_query, threads => 1|0, sortfield => $field, reverse => 1|0, maxnum => $max_results)
Search the message Xapian database.
=back
=cut
sub _next {
my($self) = @_;
my $href = $self->_parse();
unless ($href) {
$self->_read();
$href = $self->_parse();
}
return $href;
}
sub find {
my($self,@args) = @_;
my $results = { 'found' => 0, 'results' => [] };
my $resp = $self->_execute('find',@args);
return undef unless $resp;
die("mup: protocol broken!? missing (:erase t)") unless $resp->{'erase'};
my $result = $self->_next();
while ($result) {
if (exists($result->{'found'})) {
$results->{'found'} = int($result->{'found'});
$result = undef;
} elsif (!exists($result->{'docid'})) {
local $Data::Dumper::Terse = 1;
local $Data::Dumper::Indent = 0;
warn("mup: unexpected find result w/no docid: ".Dumper($result));
$result = undef;
} else {
push(@{$results->{'results'}}, $result);
$result = $self->_next();
}
}
return $results;
}
=pod
=over 4
=item * index (path => $path, my-addresses: 'me,and,mine', callback => $sub)
(Re)index the messagebase. The mu server updates us with progress
every 500 messages. By default we only return the final result
after all indexing has occurred but if the caller wants to e.g. update
a progress meter or something it can pass us a special C<callback>
argument that is invoked with every progress report given to us by
the server.
=back
=cut
sub default_maildir { $ENV{'HOME'} . '/Maildir' };
sub _our_maildir {
return shift->maildir || $ENV{'MAILDIR'} || default_maildir();
}
sub index {
my $self = shift(@_);
my $argref = _refify(@_);
$argref->{'path'} ||= $self->_our_maildir();
my $cb = $argref->{'callback'};
delete($argref->{'callback'}) if $cb;
# The index command is special. Unlike the others, we don't
# necessarily send a command and get back a single response.
# Instead we may get back a series of responses, one for each
# 500 messages indexed. Only the last one will be marked with
# 'status' => 'complete', so wait for that and swallow the rest.
my $href = $self->_execute('index',$argref);
return undef unless $href;
while ($href && $href->{'status'} ne 'complete') {
my($status,$pr,$up,$cl) =
map { $href->{$_} } qw(status processed updated cleaned_up);
warn("mup: index $status: $pr processed, $up updated, $cl cleaned\n")
if $self->verbose;
&$cb($href) if $cb;
$self->_read();
my $tmp = $href;
do {
$tmp = $self->_parse(); # can call _read()
&$cb($tmp) if $cb;
$href = $tmp if $tmp;
} while ($tmp && $tmp->{'status'} ne 'complete');
}
return $href;
}
=pod
=over 4
=item * mkdir (path => $path)
Make a new maildir under your Maildir basedir.
=back
=cut
sub mkdir {
my $self = shift(@_);
my $argref = _refify(@_);
# Make path relative to our Maildir unless it is absolute
my $path = $argref->{'path'};
die("mup: path is required") unless $path;
$path = join("/",$self->_our_maildir(),$path) unless $path =~ /^\//;
warn("mup: mkdir ".$argref->{'path'}." => mkdir $path\n")
if $self->verbose;
$argref->{'path'} = $path;
$self->_execute('mkdir',$argref);
}
=pod
=over 4
=item * move ( docid => $docid | msgid => $msgid, maildir => $path, flags => $flags)
Move a message from one maildir folder to another.
=back
=cut
sub move {
my $self = shift(@_);
my $argref = _refify(@_);
# Unlike mkdir's path arg, our maildir arg must start with a slash
my $maildir = $argref->{'maildir'};
$argref->{'maildir'} = "/$maildir" unless $maildir =~ /^\//;
$self->no_updates(1);
my $result = $self->_execute('move',$argref);
$self->no_updates(0);
return $result;
}
=pod
=over 4
=item * ping ()
Ping the server to make sure it is alive.
=back
=cut
sub ping { shift->_execute('ping',@_); }
=pod
=over 4
=item * remove (docid => $docid)
Remove a message by document ID.
=back
=cut
sub remove { shift->_execute('remove',@_); }
=pod
=over 4
=item * view ( docid => $docid | msgid => $msgid | path => $path, extract_images => 1|0, use_agent => 1|0, auto_retrieve_key => 1|0)
Return a canonicalized view of a message, optionally with images
and/or cryptography (PGP) dealt with. The message can be specified by
C<docid>, C<msgid> or as a path to a file containing the message.
=back
=cut
sub view { shift->_execute('view',@_); }
########################################################################
no Moose;
__PACKAGE__->meta->make_immutable;
1;
__END__
=pod
=head1 SEE ALSO
L<mu(1)>, L<mu-server(1)>
=head1 AUTHOR
attila <attila@stalphonsos.com>
=head1 LICENSE
Copyright (C) 2015 by attila <attila@stalphonsos.com>
Permission to use, copy, modify, and distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
=cut
##
# Local variables:
# mode: perl
# tab-width: 4
# perl-indent-level: 4
# cperl-indent-level: 4
# cperl-continued-statement-offset: 4
# indent-tabs-mode: nil
# comment-column: 40
# End:
##

47
perl/t/001-basics.t Normal file
View File

@ -0,0 +1,47 @@
#!/usr/bin/perl
##
# 001-basics.t - basic mup tests
##
# Copyright (C) 2015 by attila <attila@stalphonsos.com>
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
# WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
# AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
# DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
# PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
# TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
##
use strict;
use warnings;
use Test::More tests => 4;
use Data::Dumper;
use mup;
use t::lib;
# basic tests: constructor, ping, finish
my $mu = mup->new(verbose => $ENV{'TEST_VERBOSE'});
ok($mu,"constructor won: $mu");
my $p = $mu->ping(timeout => 2);
ok($p,"ping returned:".Dumper($p));
my $p2 = $mu->ping();
ok($p2,"ping2 returned:".Dumper($p2));
ok($mu->finish(),"finish won");
##
# Local variables:
# mode: perl
# tab-width: 4
# perl-indent-level: 4
# perl-continued-statement-offset: 4
# indent-tabs-mode: nil
# comment-column: 40
# End:
##

53
perl/t/002-index.t Normal file
View File

@ -0,0 +1,53 @@
#!/usr/bin/perl
##
# 002-index.t - try the index command
##
# Copyright (C) 2015 by attila <attila@stalphonsos.com>
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
# WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
# AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
# DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
# PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
# TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
##
use strict;
use warnings;
use Data::Dumper;
use mup;
use Test::More tests => 4;
use t::lib;
sub update_status {
my($href) = @_;
return unless $ENV{'TEST_VERBOSE'};
local $Data::Dumper::Terse = 1; # cheesy
local $Data::Dumper::Indent = 0;
warn("$0: update_status: ".Dumper($href)."\n");
}
my $mu = mup->new(verbose => $ENV{'TEST_VERBOSE'});
ok($mu,"constructor won");
my $i = $mu->index();
ok($i,"index won: ".Dumper($i));
my $j = $mu->index(callback => \&update_status);
ok($j,"index w/callback won");
ok($mu->finish(),"finish won");
##
# Local variables:
# mode: perl
# tab-width: 4
# perl-indent-level: 4
# perl-continued-statement-offset: 4
# indent-tabs-mode: nil
# comment-column: 40
# End:
##

55
perl/t/003-contacts.t Normal file
View File

@ -0,0 +1,55 @@
#!/usr/bin/perl
##
# 003-contacts.t - exercise 'contacts' command
##
# Copyright (C) 2015 by attila <attila@stalphonsos.com>
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
# WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
# AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
# DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
# PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
# TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
##
use strict;
use warnings;
use mup;
use Test::More tests => 10;
use t::lib;
my $mu = mup->new(verbose => $ENV{'TEST_VERBOSE'});
ok($mu,"constructor won");
my $c = $mu->contacts;
ok(ref($c) eq 'HASH',"contacts returned a hashref");
ok(ref($c->{'contacts'}) eq 'ARRAY',"contacts returned an array");
my @clist = map { $_->{'mail'} } @{$c->{'contacts'}};
ok(scalar(@clist) == 5,"right number of contacts in array".join(", ",@clist));
sub have {
my($a,@l) = @_;
my $n = grep { $_ eq $a } @l;
ok($n, "$a is in the list");
}
have('tech@openbsd.org',@clist);
have('habeus@stalphonsos.com',@clist);
have('guenther@gmail.com',@clist);
have('mark.kettenis@xs4all.nl',@clist);
have('slashdot@newsletters.slashdot.org',@clist);
ok($mu->finish(),"finish won");
##
# Local variables:
# mode: perl
# tab-width: 4
# perl-indent-level: 4
# perl-continued-statement-offset: 4
# indent-tabs-mode: nil
# comment-column: 40
# End:
##

55
perl/t/004-add.t Normal file
View File

@ -0,0 +1,55 @@
#!/usr/bin/perl
##
# 004-add.t - try the 'add' command
##
# Copyright (C) 2015 by attila <attila@stalphonsos.com>
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
# WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
# AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
# DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
# PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
# TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
##
use strict;
use warnings;
use mup;
use Test::More tests => 3;
use Cwd qw(abs_path);
use Data::Dumper;
use t::lib;
sub up {
return unless $ENV{'TEST_VERBOSE'};
my($upd) = @_;
local $Data::Dumper::Terse = 1;
local $Data::Dumper::Indent = 0;
warn("004-add.t: update: ".Dumper($upd)."\n");
}
die("004-add.t: where is my t/sample.eml?") unless -f "t/sample.eml";
my $sample = abs_path("t/sample.eml");
my $mu = mup->new(verbose => $ENV{'TEST_VERBOSE'}, update_callback => \&up);
ok($mu,"constructor won");
my $a = $mu->add(path => $sample);
ok($a,"add won: ".Dumper($a));
ok($mu->finish(),"finish won");
##
# Local variables:
# mode: perl
# tab-width: 4
# perl-indent-level: 4
# perl-continued-statement-offset: 4
# indent-tabs-mode: nil
# comment-column: 40
# End:
##

48
perl/t/005-find.t Normal file
View File

@ -0,0 +1,48 @@
#!/usr/bin/perl
##
# 005-find.t - exercise the 'find' command
##
# Copyright (C) 2015 by attila <attila@stalphonsos.com>
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
# WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
# AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
# DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
# PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
# TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
##
use strict;
use warnings;
use mup;
use Test::More tests => 8;
use t::lib;
my $mu = mup->new(verbose => $ENV{'TEST_VERBOSE'});
ok($mu,"constructor won");
my $f = $mu->find(query => "openbsd");
ok($f,"find returned something");
ok($f->{'found'} == 1,"found the right number of messages");
ok(scalar(@{$f->{'results'}}) == 1,"count of results agrees");
ok($f->{'results'}->[0]->{'subject'} eq 'Re: C-state FFH on x41',"found the right one");
$f = $mu->find(query => "supercalifragilistic");
ok($f,"query worked");
ok($f->{'found'} == 0,"and found nothing, as expected");
ok($mu->finish(),"finish won");
##
# Local variables:
# mode: perl
# tab-width: 4
# perl-indent-level: 4
# perl-continued-statement-offset: 4
# indent-tabs-mode: nil
# comment-column: 40
# End:
##

50
perl/t/006-move.t Normal file
View File

@ -0,0 +1,50 @@
#!/usr/bin/perl
##
# 006-move.t - move messages between folders
##
# Copyright (C) 2015 by attila <attila@stalphonsos.com>
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
# WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
# AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
# DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
# PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
# TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
##
use strict;
use warnings;
use mup;
use Test::More tests => 7;
use Data::Dumper;
use t::lib;
my $mu = mup->new(verbose => $ENV{'TEST_VERBOSE'});
ok($mu,"constructor won");
my $f = $mu->find(query => "openbsd");
ok($f,"find returned something");
ok($f->{'found'} > 0,"found something");
my $d = $f->{'results'}->[0]->{'docid'};
my $m = $mu->mkdir(path => 'foo');
ok($m,"mkdir returned something");
my $v = $mu->move(docid => $d, maildir => 'foo');
ok($v,"move returned something");
ok(exists($v->{'update'}),"move result looks right");
ok($mu->finish(),"finish won");
##
# Local variables:
# mode: perl
# tab-width: 4
# perl-indent-level: 4
# perl-continued-statement-offset: 4
# indent-tabs-mode: nil
# comment-column: 40
# End:
##

47
perl/t/007-remove.t Normal file
View File

@ -0,0 +1,47 @@
#!/usr/bin/perl
##
# 007-remove.t - test removing messages
##
# Copyright (C) 2015 by attila <attila@stalphonsos.com>
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
# WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
# AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
# DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
# PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
# TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
##
use strict;
use warnings;
use mup;
use Test::More tests => 6;
use t::lib;
my $mu = mup->new(verbose => $ENV{'TEST_VERBOSE'});
ok($mu,"constructor won");
my $f = $mu->find(query => "openbsd");
ok($f,"find returned something");
ok($f->{'found'} > 0,"found something");
my $d = $f->{'results'}->[0]->{'docid'};
my $r = $mu->remove(docid => $d);
ok($r,"remove returned something");
ok($r->{'remove'} eq $d,"and it even looks right");
ok($mu->finish(),"finish won");
##
# Local variables:
# mode: perl
# tab-width: 4
# perl-indent-level: 4
# perl-continued-statement-offset: 4
# indent-tabs-mode: nil
# comment-column: 40
# End:
##

44
perl/t/008-view.t Normal file
View File

@ -0,0 +1,44 @@
#!/usr/bin/perl
##
# 008-view.t - test the 'view' command
##
# Copyright (C) 2015 by attila <attila@stalphonsos.com>
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
# WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
# AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
# DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
# PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
# TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
##
use strict;
use warnings;
use mup;
use Test::More tests => 5;
use t::lib;
my $mu = mup->new(verbose => $ENV{'TEST_VERBOSE'});
ok($mu,"constructor won");
my $v = $mu->view(docid => 1);
ok($v,"view returned something");
ok(exists($v->{'view'}),"view has a view element");
ok($v->{'view'}->{'docid'} == 1,"it has the right docid");
ok($mu->finish(),"finish won");
##
# Local variables:
# mode: perl
# tab-width: 4
# perl-indent-level: 4
# perl-continued-statement-offset: 4
# indent-tabs-mode: nil
# comment-column: 40
# End:
##

56
perl/t/009-extract.t Normal file
View File

@ -0,0 +1,56 @@
#!/usr/bin/perl
##
# 008-extract.t - test the 'extract' command
##
# Copyright (C) 2015 by attila <attila@stalphonsos.com>
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
# WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
# AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
# DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
# PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
# TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
##
use strict;
use warnings;
use mup;
use Test::More tests => 8;
use Cwd qw(abs_path);
use File::Temp qw/ :POSIX /;
use t::lib;
die("009-extract.t: where is my t/sample.eml?") unless -f "t/sample.eml";
my $sample = abs_path("t/sample.eml");
my $tmpx = tmpnam();
END { unlink($tmpx) if -f $tmpx; }
my $mu = mup->new(verbose => $ENV{'TEST_VERBOSE'});
ok($mu,"constructor won");
my $a = $mu->add(path => $sample);
ok($a,"add seems to have won");
my $id = $a->{'docid'};
ok($id,"new email has docid $id");
ok(!(-f $tmpx),"temp file does not yet exist");
my $x = $mu->extract(docid => $id,path => $tmpx,action => 'save',index => 1);
ok($x,"extract returned something");
ok($x->{'info'} eq 'save',"looks right");
ok(-f $tmpx,"looks like extraction worked");
ok($mu->finish(),"finish won");
##
# Local variables:
# mode: perl
# tab-width: 4
# perl-indent-level: 4
# perl-continued-statement-offset: 4
# indent-tabs-mode: nil
# comment-column: 40
# End:
##

55
perl/t/010-compose.t Normal file
View File

@ -0,0 +1,55 @@
#!/usr/bin/perl
##
# 008-compose.t - test the 'compose' command
##
# Copyright (C) 2015 by attila <attila@stalphonsos.com>
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
# WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
# AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
# DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
# PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
# TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
##
use strict;
use warnings;
use mup;
use Test::More tests => 9;
use Cwd qw(abs_path);
use t::lib;
die("010-compose.t: where is my t/sample.eml?") unless -f "t/sample.eml";
my $sample = abs_path("t/sample.eml");
my $mu = mup->new(verbose => $ENV{'TEST_VERBOSE'});
ok($mu,"constructor won");
my $a = $mu->add(path => $sample);
ok($a,"add seems to have won");
my $id = $a->{'docid'};
ok($id,"new email has docid $id");
my $c = $mu->compose(type => 'reply', docid => $id);
ok($c,"compose returned something");
my @k = sort keys(%$c);
ok(scalar(@k) == 3,"right number of keys");
ok($k[0] eq 'compose',"first is compose");
ok($k[1] eq 'include',"second is include");
ok($k[2] eq 'original',"third is original");
ok($mu->finish(),"finish won");
##
# Local variables:
# mode: perl
# tab-width: 4
# perl-indent-level: 4
# perl-continued-statement-offset: 4
# indent-tabs-mode: nil
# comment-column: 40
# End:
##

97
perl/t/lib.pm Normal file
View File

@ -0,0 +1,97 @@
#! perl
# Copyright (C) 2015 by attila <attila@stalphonsos.com>
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
# WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
# AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
# DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
# PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
# TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
package main;
use File::Path qw(make_path remove_tree);
# ensure a testworthy Maildir is available and pointed at by $ENV{MAILDIR}
sub setup_testing_envars {
if (-x '../../mu/mu') {
$ENV{'MUP_MU_BIN'} = '../../mu/mu';
}
if (-x '../mu/mu') {
$ENV{'MUP_MU_BIN'} = '../mu/mu';
}
warn("MUP_MU_BIN is $ENV{MUP_MU_BIN}\n") if $ENV{'TEST_VERBOSE'};
}
sub setup_testing_maildir {
my $verbose = $ENV{'TEST_VERBOSE'};
if ($ENV{'MAILDIR'}) {
warn("setup_testing_maildir: MAILDIR is already ".$ENV{'MAILDIR'}."\n")
if $verbose;
return;
}
my $tmpd = $ENV{'TMPDIR'} || '/tmp';
my $md = $tmpd . "/mup_t_maildir.$$";
my $cmd;
# 1. ensure the test maildir did not exist first and then create it
die("setup_testing_maildir: $md exists!") if (-d $md || -f $md);
make_path($md) or die("setup_testing_maildir: mkdir $md: $!");
$ENV{'MAILDIR'} = $md;
$ENV{'MUP_TEST_MAILDIR_SET'} = 1;
warn("setup_testing_maildir: $md\n") if $verbose;
# 2. populate it with some test data
if (!(-d "t/sample.maildir")) {
warn("setup_testing_maildir: no t/sample.maildir available!\n")
if $verbose;
} else {
my $tar = $ENV{'MUP_TEST_TAR'} || 'tar';
my $xf = $verbose ? 'xvf' : 'xf';
$cmd = qq{sh -c '(cd t/sample.maildir; ${tar} -cf - .) | (cd $md; ${tar} -$xf -)'};
system($cmd) == 0 or die("seutp_testing_maildir: $cmd: $!");
}
# 3. (optional) set up .mu under the maildir unless we are told not to
unless ($ENV{'MUP_MU_HOME'}) {
my $muhome = "$md/.mu";
make_path($muhome) or die("setup_testing_maildir: $md/.mu: $!");
$ENV{'MUP_MU_HOME'} = $muhome;
warn("seting_testing_maildir: $muhome\n") if $verbose;
my $mu_opts = $verbose ? '-d --log-stderr ' : '';
my $bin = $ENV{'MUP_MU_BIN'} || 'mu';
my $cmd = qq{$bin index ${mu_opts}--muhome=${muhome}};
warn("indexing: $cmd\n") if $verbose;
system($cmd) == 0 or die("setup_testing_maildir: $cmd: $!");
}
}
sub setup_testing_env {
setup_testing_envars;
setup_testing_maildir;
}
END {
remove_tree($ENV{'MAILDIR'},{ verbose => $ENV{'TEST_VERBOSE'} })
if ($ENV{'MAILDIR'} && $ENV{'MUP_TEST_MAILDIR_SET'} &&
!$ENV{'MUP_TEST_KEEP_MAILDIR'});
}
setup_testing_env unless $ENV{'MUP_TEST_NO_SETUP'};
1;
##
# Local variables:
# mode: perl
# tab-width: 4
# perl-indent-level: 4
# cperl-indent-level: 4
# cperl-continued-statement-offset: 4
# indent-tabs-mode: nil
# comment-column: 40
# End:
##

319
perl/t/sample.eml Normal file
View File

@ -0,0 +1,319 @@
From: attila <attila@stalphonsos.com>
Content-Transfer-Encoding: 7bit
Subject: [PATCH] Man pages: usbd_open_pipe(9), usbd_close_pipe(9)
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="=-=-="
To: tech@openbsd.org
Sender: attila <attila@stalphonsos.com>
X-Mailer: flail 1.0.2 - http://flail.org
Date: Sat, 02 May 2015 08:44:11 CDT
Return-Path: <attila@stalphonsos.com>
0:
--=-=-=
Content-Type: text/plain
Hi tech@,
This patch adds man pages for usbd_open_pipe, usbd_open_pipe_intr,
usbd_close_pipe and usbd_abort_pipe, done as two files:
usbd_open_pipe.9 and usbd_close_pipe.9. It also adds these two new .9
files to the appropriate Makefile and tweaks usbd_transfer(9) to refer
to usbd_open_pipe(9).
Comments, feedback most welcome.
Pax, -A
P.S. I f'ing love mandoc. Just sayin...
--
attila@stalphonsos.com | http://trac.haqistan.net/~attila
keyid E6CC1EDB | 4D91 1B98 A210 1D71 2A0E AC29 9677 D0A6 E6CC 1EDB
--=-=-=
Content-Type: text/x-patch
Content-Disposition: inline; filename=usbd_man_pages.diff
Content-Description: man pages: usbd_open_pipe(9), usbd_close_pipe(9)
Index: Makefile
===================================================================
RCS file: /cvs/src/share/man/man9/Makefile,v
retrieving revision 1.230
diff -u -p -r1.230 Makefile
--- Makefile 10 Feb 2015 21:56:08 -0000 1.230
+++ Makefile 2 May 2015 00:07:16 -0000
@@ -31,7 +31,7 @@ MAN= aml_evalnode.9 atomic_add_int.9 ato
tsleep.9 spl.9 startuphook_establish.9 \
socreate.9 sosplice.9 style.9 syscall.9 systrace.9 sysctl_int.9 \
task_add.9 tc_init.9 time.9 timeout.9 tvtohz.9 uiomove.9 uvm.9 \
- usbd_transfer.9 \
+ usbd_transfer.9 usbd_open_pipe.9 usbd_close_pipe.9 \
vfs.9 vfs_busy.9 \
vfs_cache.9 vaccess.9 vclean.9 vcount.9 vdevgone.9 vfinddev.9 vflush.9 \
vflushbuf.9 vget.9 vgone.9 vhold.9 vinvalbuf.9 vnode.9 vnsubr.9 \
Index: usbd_close_pipe.9
===================================================================
RCS file: usbd_close_pipe.9
diff -N usbd_close_pipe.9
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ usbd_close_pipe.9 2 May 2015 00:07:16 -0000
@@ -0,0 +1,59 @@
+.\" $OpenBSD$
+.\"
+.\" Copyright (c) 2015 Sean Levy <attila@stalphonsos.com>
+.\"
+.\" Permission to use, copy, modify, and distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+.\"
+.Dd $Mdocdate$
+.Dt USBD_CLOSE_PIPE 9
+.Os
+.Sh NAME
+.Nm usbd_close_pipe , usbd_abort_pipe
+.Nd close or abort transfers on a USB pipe
+.Sh SYNOPSIS
+.In dev/usb/usb.h
+.In dev/usb/usbdi.h
+.Ft usbd_status
+.Fn usbd_close_pipe "struct usbd_pipe *pipe"
+.Ft usbd_status
+.Fn usbd_abort_pipe "struct usbd_pipe *pipe"
+.Sh DESCRIPTION
+A pipe is a logical connection between the host and an endpoint
+on a USB device, created by one of
+.Xr usbd_open_pipe 9
+or
+.Xr usbd_open_pipe_intr 9 .
+.Pp
+The
+.Fn usbd_abort_pipe
+function aborts any transfers queued on the pipe and ensures it is quiescent
+before returning.
+.Pp
+The
+.Fn usbd_close_pipe
+function first calls
+.Fn usbd_abort_pipe ,
+then removes the pipe from the relevant USB interface's list of pipes
+and cleans up any memory associated with the pipe, including any
+implicit transfer created by
+.Xr usbd_open_pipe_intr 9 .
+.Sh CONTEXT
+.Fn usbd_abort_pipe
+and
+.Fn usbd_close_pipe
+can be called during autoconf, from process context or from interrupt
+context.
+.Sh SEE ALSO
+.Xr usbd_open_pipe 9 ,
+.Xr usb 4 ,
+.Xr intro 4
Index: usbd_open_pipe.9
===================================================================
RCS file: usbd_open_pipe.9
diff -N usbd_open_pipe.9
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ usbd_open_pipe.9 2 May 2015 00:07:16 -0000
@@ -0,0 +1,162 @@
+.\" $OpenBSD$
+.\"
+.\" Copyright (c) 2015 Sean Levy <attila@stalphonsos.com>
+.\"
+.\" Permission to use, copy, modify, and distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+.\"
+.Dd $Mdocdate$
+.Dt USBD_OPEN_PIPE 9
+.Os
+.Sh NAME
+.Nm usbd_open_pipe , usbd_open_pipe_intr
+.Nd create USB pipe
+.Sh SYNOPSIS
+.In dev/usb/usb.h
+.In dev/usb/usbdi.h
+.Ft usbd_status
+.Fn usbd_open_pipe "struct usbd_interface *iface" "u_int8_t address" "u_int8_t flags" "struct usbd_pipe **pipe"
+.Ft usbd_status
+.Fn usbd_open_pipe_intr "struct usbd_interface *iface" "u_int8_t address" "u_int8_t flags" "struct usbd_pipe **pipe" "void *priv" "void *buffer" "u_int32_t len" "usbd_callback cb" "int ival"
+.Sh DESCRIPTION
+The
+.Fn usbd_open_pipe
+and
+.Fn usbd_open_pipe_intr
+functions create pipes.
+A pipe is a logical connection between the host and an endpoint on a
+USB device.
+USB drivers use pipes to manage transfers to or from a USB
+endpoint.
+.Pp
+The
+.Fn usbd_open_pipe
+function takes the following arguments:
+.Bl -tag -width callback
+.It Fa iface
+the USB interface for which the pipe is to be created.
+.It Fa address
+The endpoint in that interface to which the pipe should be connected.
+.It Fa flags
+A bitmask of flags. Currently there is only one flag bit defined:
+.Bl -tag -width xxx -offset indent
+.It Dv USBD_EXCLUSIVE_ACCESS
+Do not allow other pipes to use this endpoint on this interface
+while this pipe exists.
+.El
+.It Fa pipe
+A pointer to where the resulting
+.Ql struct usbd_pipe *
+should be stored if the call is successful.
+.El
+.Pp
+The
+.Fn usbd_open_pipe_intr
+takes the following arguments:
+.Bl -tag -width callback
+.It Fa iface
+The USB interface for which the pipe is to be created.
+.It Fa address
+The endpoint in that interface to which the pipe should be connected.
+.It Fa flags
+A bitmask of flags. These flags are not interpreted in the same
+way as the
+.Fa flags
+passed to
+.Fn usbd_open_pipe .
+Instead,
+.Fn usbd_open_pipe_intr
+implicitly turns on the
+.Dv USBD_EXCLUSIVE_ACCESS
+bit for the pipe, disallowing multiple interrupt pipes for
+the same endpoint. The
+.Fa flags
+argument in this case is instead passed directly to
+.Xr usbd_setup_xfer 9
+as its
+.Fa flags
+argument, whose interpretation is documented in
+its man page.
+.It Fa pipe
+A pointer to where the resulting
+.Ql struct usbd_pipe *
+should be stored if the call is successful.
+.It Fa priv
+A pointer to a private cookie untouched by the USB stack for reuse in
+the callback specified by the
+.Fa cb
+argument.
+.It Fa buffer
+A pointer to the data buffer for use by the implicit transfer
+(see below).
+.It Fa len
+The length in bytes of
+.Fa buffer .
+.It Fa cb
+A callback invoked every time the interrupt transfer completes.
+.It Fa ival
+The interval in milliseconds with which the interrupt pipe
+should be polled by the USB stack.
+.El
+.Pp
+Pipes created by
+.Fn usbd_open_pipe_intr
+implicitly have a repeating transfer queued on them which
+is run every
+.Fa ival
+milliseconds.
+This implicit transfer is not automatically removed from the list of
+transfers maintained by the pipe, unlike normal transfers, and will
+continue to be processed every
+.Fa ival
+milliseconds.
+.Pp
+These functions return
+.Dv USBD_NORMAL_COMPLETION
+when they are successful; in both cases
+.Ql *pipe
+will contain the newly created pipe.
+Both functions can return
+.Dv USBD_IN_USE
+if the interface/address pair already has a pipe associated with it;
+in the case of
+.Fn usbd_open_pipe
+this happens only if
+.Dv USBD_EXCLUSIVE_ACCESS
+is turned on in
+.Fa flags .
+For
+.Fn usbd_open_pipe_intr
+this flag is always assumed, so any attempt to create multiple
+pipes to the same interrupt endpoint on the same interface will
+return
+.Dv USBD_IN_USE.
+Both functions can also return
+.Dv USBD_NOMEM
+if they fail to allocate memory for any reason.
+In addition,
+.Fn usbd_open_pipe_intr
+can return any error code returned by
+.Xr usbd_setup_xfer 9
+or
+.Xr usbd_transfer 9 .
+.Sh CONTEXT
+.Fn usbd_open_pipe
+and
+.Fn usbd_open_pipe_intr
+can be called during autoconf, from process context,
+or from interrupt context.
+.Sh SEE ALSO
+.Xr usbd_transfer 9 ,
+.Xr usbd_close_pipe 9 ,
+.Xr usb 4 ,
+.Xr intro 4
Index: usbd_transfer.9
===================================================================
RCS file: /cvs/src/share/man/man9/usbd_transfer.9,v
retrieving revision 1.5
diff -u -p -r1.5 usbd_transfer.9
--- usbd_transfer.9 12 Jul 2014 16:07:06 -0000 1.5
+++ usbd_transfer.9 2 May 2015 00:07:16 -0000
@@ -31,7 +31,10 @@
.Fn usbd_transfer "struct usbd_xfer *xfer"
.Sh DESCRIPTION
These functions provide a controller independent mechanism to perform USB
-data transfers.
+data transfers. They make use of a pipe created by
+.Xr usbd_open_pipe 9
+or
+.Xr usbd_open_pipe_intr 9 .
.Pp
The function
.Fn usbd_setup_xfer
@@ -104,6 +107,8 @@ if
has not been passed via
.Fa flags .
.Sh SEE ALSO
+.Xr usbd_open_pipe 9 ,
+.Xr usbd_open_pipe_intr 9 ,
.Xr ehci 4 ,
.Xr ohci 4 ,
.Xr uhci 4 ,
--=-=-=--

View File

@ -0,0 +1,200 @@
Return-Path: <owner-tech+M42749@openbsd.org>
Delivered-To: attila@stalphonsos.com
Received: (qmail 37697 invoked from network); 28 Jun 2015 22:20:10 -0000
Received: from unknown (HELO shear.ucar.edu) (192.43.244.163)
by x.stalphonsos.net with SMTP; 28 Jun 2015 22:20:10 -0000
Received: from openbsd.org (localhost [127.0.0.1])
by shear.ucar.edu (8.14.7/8.14.7) with ESMTP id t5SMJRQT000203;
Sun, 28 Jun 2015 16:19:27 -0600 (MDT)
Received: from mail-pa0-f51.google.com (mail-pa0-f51.google.com [209.85.220.51])
by shear.ucar.edu (8.14.7/8.14.7) with ESMTP id t5SMJGwf030092
(version=TLSv1/SSLv3 cipher=DHE-DSS-AES128-SHA bits=128 verify=FAIL)
for <tech@openbsd.org>; Sun, 28 Jun 2015 16:19:17 -0600 (MDT)
Received: by padev16 with SMTP id ev16so94981036pad.0
for <tech@openbsd.org>; Sun, 28 Jun 2015 15:19:16 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
d=gmail.com; s=20120113;
h=date:from:to:cc:subject:in-reply-to:message-id:references
:user-agent:mime-version:content-type;
bh=4q12s9+CtyHZEDQlC5XvVo3VnQHQCA5Vt6JwqbU9Adc=;
b=UVS7CgpSvUmIQMP7SOv8c1FO5cj2765fmTE2FwHVGkUahh/tuqT1uQGa7tfG7/1vbL
y4FPwhokPb+Q8mLKI3qIEfdgmQzhq1QcT6kkvNrRe7UuybMQhDJKwZuPAd7KcaS1kigX
GMS8P3DxB3PMoNOKoYUomd5X4Xm4MT/68ifl+4g1WiWD5BkLdqG5G8MaFo3B6W0E+h+1
XNNK2B4BSJF28WswgAXzEshV4Sr/Uju0a5I/1sh3QYkZ3XCZRJeQpd14je0O5Z9ivj3P
3EW+CQZmiStJ+A9CCsMhGUoMFhJFcbZ6LDd8bJKkcsGPZ85zmFfcUubODSA/lRtkW6Gi
RtkA==
X-Received: by 10.70.48.68 with SMTP id j4mr25375231pdn.111.1435529956338;
Sun, 28 Jun 2015 15:19:16 -0700 (PDT)
Received: from the-guenther.attlocal.net (76-253-1-113.lightspeed.sntcca.sbcglobal.net. [76.253.1.113])
by mx.google.com with ESMTPSA id v8sm40045232pdm.89.2015.06.28.15.19.14
(version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128);
Sun, 28 Jun 2015 15:19:15 -0700 (PDT)
Date: Sun, 28 Jun 2015 15:19:13 -0700
From: Philip Guenther <guenther@gmail.com>
X-X-Sender: guenther@morgaine.local
To: Mark Kettenis <mark.kettenis@xs4all.nl>
cc: tech@openbsd.org
Subject: Re: C-state FFH on x41
In-Reply-To: <201506281537.t5SFbZs6031688@glazunov.sibelius.xs4all.nl>
Message-ID: <alpine.BSO.2.20.1506281513280.27877@morgaine.local>
References: <201506281537.t5SFbZs6031688@glazunov.sibelius.xs4all.nl>
User-Agent: Alpine 2.20 (BSO 67 2015-01-07)
MIME-Version: 1.0
Content-Type: text/plain; charset=US-ASCII
List-Help: <mailto:majordomo@openbsd.org?body=help>
List-ID: <tech.openbsd.org>
List-Owner: <mailto:owner-tech@openbsd.org>
List-Post: <mailto:tech@openbsd.org>
List-Subscribe: <mailto:majordomo@openbsd.org?body=sub%20tech>
List-Unsubscribe: <mailto:majordomo@openbsd.org?body=unsub%20tech>
X-Loop: tech@openbsd.org
Precedence: list
Sender: owner-tech@openbsd.org
On Sun, 28 Jun 2015, Mark Kettenis wrote:
> I have an x41 that prints the following in dmesg:
>
> acpicpu0 at acpi0
> C1: unknown FFH vendor 8: !C3(250@85 io@0x1015), C2(500@1 io@0x1014), PSS
>
> The relevant AML indead has that strange value in the "Bit Width" field:
...
> Obviously this ACPI BIOS is buggy and perhaps we should indeed
> complain. But we also should include a C1 HALT state in the list
> regardless, and I don't think we currently do that.
Give the diff below a try. It inserts a fallback "C1-via-halt" state
before parsing the _CST objects, overwriting it if a valid _CST C1 state
is found. If no valid _CST C1 was found, the fallback should show in
dmesg as "C1(@1 halt!)".
As a side-benefit, this renders a couple paranoia checks obsolete in
acpicpu_idle().
Index: dev/acpi/acpicpu.c
===================================================================
RCS file: /data/src/openbsd/src/sys/dev/acpi/acpicpu.c,v
retrieving revision 1.64
diff -u -p -r1.64 acpicpu.c
--- dev/acpi/acpicpu.c 13 Jun 2015 21:41:42 -0000 1.64
+++ dev/acpi/acpicpu.c 28 Jun 2015 21:55:51 -0000
@@ -77,7 +77,7 @@ void acpicpu_setperf_ppc_change(struct a
/* flags on Intel's FFH mwait method */
#define CST_FLAG_MWAIT_HW_COORD 0x1
#define CST_FLAG_MWAIT_BM_AVOIDANCE 0x2
-#define CST_FLAG_UP_ONLY 0x4000 /* ignore if MP */
+#define CST_FLAG_FALLBACK 0x4000 /* fallback for broken _CST */
#define CST_FLAG_SKIP 0x8000 /* state is worse choice */
#define FLAGS_MWAIT_ONLY 0x02
@@ -339,7 +339,13 @@ acpicpu_add_cstate(struct acpicpu_softc
dnprintf(10," C%d: latency:.%4x power:%.4x addr:%.16llx\n",
state, latency, power, address);
- cx = malloc(sizeof(*cx), M_DEVBUF, M_WAITOK);
+ /* add a new state, or overwrite the fallback C1 state? */
+ if (state != ACPI_STATE_C1 ||
+ (cx = SLIST_FIRST(&sc->sc_cstates)) == NULL ||
+ (cx->flags & CST_FLAG_FALLBACK) == 0) {
+ cx = malloc(sizeof(*cx), M_DEVBUF, M_WAITOK);
+ SLIST_INSERT_HEAD(&sc->sc_cstates, cx, link);
+ }
cx->state = state;
cx->method = method;
@@ -347,8 +353,6 @@ acpicpu_add_cstate(struct acpicpu_softc
cx->latency = latency;
cx->power = power;
cx->address = address;
-
- SLIST_INSERT_HEAD(&sc->sc_cstates, cx, link);
}
/* Found a _CST object, add new cstate for each entry */
@@ -489,9 +493,18 @@ acpicpu_getcst(struct acpicpu_softc *sc)
if (aml_evalname(sc->sc_acpi, sc->sc_devnode, "_CST", 0, NULL, &res))
return (1);
+ /* provide a fallback C1-via-halt in case _CST's C1 is bogus */
+ acpicpu_add_cstate(sc, ACPI_STATE_C1, CST_METH_HALT,
+ CST_FLAG_FALLBACK, 1, -1, 0);
+
aml_foreachpkg(&res, 1, acpicpu_add_cstatepkg, sc);
aml_freevalue(&res);
+ /* only have fallback state? then no _CST objects were understood */
+ cx = SLIST_FIRST(&sc->sc_cstates);
+ if (cx->flags & CST_FLAG_FALLBACK)
+ return (1);
+
/*
* Scan the list for states that are neither lower power nor
* lower latency than the next state; mark them to be skipped.
@@ -500,19 +513,15 @@ acpicpu_getcst(struct acpicpu_softc *sc)
* Also keep track if all the states we'll use use mwait.
*/
use_nonmwait = 0;
- if ((cx = SLIST_FIRST(&sc->sc_cstates)) == NULL)
- use_nonmwait = 1;
- else {
- while ((next_cx = SLIST_NEXT(cx, link)) != NULL) {
- if ((cx->power >= next_cx->power &&
- cx->latency >= next_cx->latency) ||
- (cx->state > 1 &&
- (sc->sc_ci->ci_feature_tpmflags & TPM_ARAT) == 0))
- cx->flags |= CST_FLAG_SKIP;
- else if (cx->method != CST_METH_MWAIT)
- use_nonmwait = 1;
- cx = next_cx;
- }
+ while ((next_cx = SLIST_NEXT(cx, link)) != NULL) {
+ if ((cx->power >= next_cx->power &&
+ cx->latency >= next_cx->latency) ||
+ (cx->state > 1 &&
+ (sc->sc_ci->ci_feature_tpmflags & TPM_ARAT) == 0))
+ cx->flags |= CST_FLAG_SKIP;
+ else if (cx->method != CST_METH_MWAIT)
+ use_nonmwait = 1;
+ cx = next_cx;
}
if (use_nonmwait)
sc->sc_flags &= ~FLAGS_MWAIT_ONLY;
@@ -581,8 +590,12 @@ acpicpu_print_one_cst(struct acpi_cstate
if (cx->power != -1)
printf("%d", cx->power);
printf("@%d%s", cx->latency, meth);
- if (cx->flags & ~CST_FLAG_SKIP)
- printf(".%x", (cx->flags & ~CST_FLAG_SKIP));
+ if (cx->flags & ~CST_FLAG_SKIP) {
+ if (cx->flags & CST_FLAG_FALLBACK)
+ printf("!");
+ else
+ printf(".%x", (cx->flags & ~CST_FLAG_SKIP));
+ }
if (show_addr)
printf("@0x%llx", cx->address);
printf(")");
@@ -1114,12 +1127,6 @@ acpicpu_idle(void)
* states marked skippable
*/
best = cx = SLIST_FIRST(&sc->sc_cstates);
- if (cx == NULL) {
-halt:
- __asm volatile("sti; hlt");
- return;
- }
-
while ((cx->flags & CST_FLAG_SKIP) ||
cx->latency * 3 > sc->sc_prev_sleep) {
if ((cx = SLIST_NEXT(cx, link)) == NULL)
@@ -1140,8 +1147,6 @@ halt:
(cx->flags & CST_FLAG_MWAIT_BM_AVOIDANCE) == 0)
break;
}
- if (cx == NULL)
- goto halt;
best = cx;
}

View File

@ -0,0 +1,168 @@
Return-Path: <newsletter@response.sourceforge.com>
Delivered-To: attila@mail.stalphonsos.net
Received: (qmail 12481 invoked by alias); 16 Nov 2014 17:02:11 -0000
Delivered-To: habeus@stalphonsos.com
Received: (qmail 12477 invoked from network); 16 Nov 2014 17:02:10 -0000
Received: from unknown (HELO smtp.clicks.slashdot.org) (74.116.233.131)
by x.stalphonsos.net with SMTP; 16 Nov 2014 17:02:10 -0000
Received: from mail3.elabs10.com (10.10.10.53) by smtp.clicks.slashdot.org id hd3c941lf140 for <habeus@stalphonsos.com>; Sun, 16 Nov 2014 09:02:10 -0800 (envelope-from <newsletter@response.sourceforge.com>)
To: <habeus@stalphonsos.com>
Subject: Slashdot Newsletter 2014-11-16
Date: Sun, 16 Nov 2014 09:02:10 -0800
DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d=newsletters.slashdot.org; s=s2010001400b;
h=Reply-To:From:List-Unsubscribe:Content-description:Content-Type:Subject:To:Date;
bh=qb2VwtQJpdaiWdlAeC1G6/iatq0=;
b=qe5NrC1E3eG48ri5aonHzV9Jnbrit2dTAqm6tcbJvNSHHb3utEiLyVSiO4RcCNPG6Tj
/hx6ndWVOfcjM8Q85p76S6JCkpd5V+vnMmktRPb9/FYCSTckqdlSyBYtHJz+oWWZawl
TW1QU40j/H+QEN/gI3rJtuxnyjIuFAr4xElHc=
X-Delivery: Custom 2010001400
Reply-To: slashdot@newsletters.slashdot.org
List-Unsubscribe: <mailto:unsubscribe-47676@elabs10.com?subject=habeus@stalphonsos.com>
Content-description: 009e97a71fhabeus%40stalphonsos.com!ba3c!3551f9!77ce2ff8!rynof10.pbz!
X-Complaints-To: abuse@elabs10.com
Message-Id: <20141116170227.009E97A71F47@elabs10.com>
Content-Type: text/plain; charset="us-ascii"
From: "Slashdot Headlines" <slashdot@newsletters.slashdot.org>
Slashdot Daily News
__________________________________________________________________________
Do You Manage Your Data or Does It Manage You?
Databases, warehouses and Big Data analytics projects are changing the way IT and the enterprise think about data management. How is your organization evolving to handle the data explosion that continues to stress developers, IT and users alike? Take our quick four-question Slashdot Pulse poll and let us know what is most important to your data efforts. Learn More!
http://clicks.slashdot.org/ct.html?ufl=0&rtr=on&s=x8pb08,22wah,10sc,g3m8,52q8,1yh,aqzj
__________________________________________________________________________
The Downside to Low Gas Prices
http://clicks.slashdot.org/ct.html?ufl=0&rtr=on&s=x8pb08,22wah,10sc,1g2t,dck5,1yh,aqzj
Japanese Maglev Train Hits 500kph
http://clicks.slashdot.org/ct.html?ufl=0&rtr=on&s=x8pb08,22wah,10sc,1w2f,ipk8,1yh,aqzj
Philae's Batteries Have Drained; Comet Lander Sleeps
http://clicks.slashdot.org/ct.html?ufl=0&rtr=on&s=x8pb08,22wah,10sc,i6u7,2e4k,1yh,aqzj
Former Police Officer Indicted For Teaching How To Pass a Polygraph Test
http://clicks.slashdot.org/ct.html?ufl=0&rtr=on&s=x8pb08,22wah,10sc,hale,m1sq,1yh,aqzj
Comcast Kisses-Up To Obama, Publicly Agrees On Net Neutrality
http://clicks.slashdot.org/ct.html?ufl=0&rtr=on&s=x8pb08,22wah,10sc,b9tp,5bcl,1yh,aqzj
Ask Slashdot: Programming Education Resources For a Year Offline?
http://clicks.slashdot.org/ct.html?ufl=0&rtr=on&s=x8pb08,22wah,10sc,2g0d,dx6s,1yh,aqzj
Alleged Satellite Photo Says Ukraine Shootdown of MH17
http://clicks.slashdot.org/ct.html?ufl=0&rtr=on&s=x8pb08,22wah,10sc,f19n,a6i,1yh,aqzj
US DOE Sets Sights On 300 Petaflop Supercomputer
http://clicks.slashdot.org/ct.html?ufl=0&rtr=on&s=x8pb08,22wah,10sc,mao5,9w51,1yh,aqzj
Ask Slashdot: Who's the Doctors Without Borders of Technology?
http://clicks.slashdot.org/ct.html?ufl=0&rtr=on&s=x8pb08,22wah,10sc,l56s,51e3,1yh,aqzj
Entrepreneur Injects Bitcoin Wallets Into Hands
http://clicks.slashdot.org/ct.html?ufl=0&rtr=on&s=x8pb08,22wah,10sc,d39v,e9ov,1yh,aqzj
Microsoft Aims To Offer Windows 10 Upgrades For All Windows Phone 8 Lumias
http://clicks.slashdot.org/ct.html?ufl=0&rtr=on&s=x8pb08,22wah,10sc,xnb,b4xz,1yh,aqzj
R. A. Montgomery, Creator of the "Choose Your Own Adventure" Books, Dead At 78
http://clicks.slashdot.org/ct.html?ufl=0&rtr=on&s=x8pb08,22wah,10sc,4ze8,vwk,1yh,aqzj
Real Steampunk Computer Brought Back To Life
http://clicks.slashdot.org/ct.html?ufl=0&rtr=on&s=x8pb08,22wah,10sc,im3k,9yj0,1yh,aqzj
AT&T Stops Using 'Super Cookies' To Track Cellphone Data
http://clicks.slashdot.org/ct.html?ufl=0&rtr=on&s=x8pb08,22wah,10sc,dbjg,lwow,1yh,aqzj
New Trial Brings Skype to (Some) Browsers
http://clicks.slashdot.org/ct.html?ufl=0&rtr=on&s=x8pb08,22wah,10sc,4v80,jg5u,1yh,aqzj
__________________________________________________________________________
What Is the Best Way to Launch an Online Business?
As businesses plan their move to the cloud, the choice of provider can be daunting. Performance, reliability and security concerns can paralyze IT before a migration ever begins. Take our quick poll to let us know what is most important to your organization when considering hosting your online presence in the cloud. Learn More!
http://clicks.slashdot.org/ct.html?ufl=0&rtr=on&s=x8pb08,22wah,10sc,fhdr,2xhz,1yh,aqzj
__________________________________________________________________________
The Downside to Low Gas Prices http://clicks.slashdot.org/ct.html?ufl=0&rtr=on&s=x8pb08,22wah,10sc,etth,jk8t,1yh,aqzj
From the speak-for-yourself-hummer-buyers department
HughPickens.com writes Pat Garofalo writes in an op-ed in US News & World Report that with the recent drop in oil prices, there's something policymakers can do that will offset at least some of the negative effects of the currently low prices,... Read More http://clicks.slashdot.org/ct.html?ufl=0&rtr=on&s=x8pb08,22wah,10sc,4pdc,d2pk,1yh,aqzj
Japanese Maglev Train Hits 500kph http://clicks.slashdot.org/ct.html?ufl=0&rtr=on&s=x8pb08,22wah,10sc,2qfj,ft06,1yh,aqzj
From the for-amtrak-that-takes-negligence department
An anonymous reader writes Japan has now put 100 passengers on a Maglev train doing over 500kph. That's well over twice as fast as the fastest U.S. train can manage, and that only manages 240kph on small sections of its route. The Japanese... Read More http://clicks.slashdot.org/ct.html?ufl=0&rtr=on&s=x8pb08,22wah,10sc,8uka,132e,1yh,aqzj
Philae's Batteries Have Drained; Comet Lander Sleeps http://clicks.slashdot.org/ct.html?ufl=0&rtr=on&s=x8pb08,22wah,10sc,lzi6,uds,1yh,aqzj
From the amazing-feats-done-dirt-dirt-cheap department
astroengine (1577233) writes "In the final hours, Philae's science team hurried to squeeze as much science out of the small lander as possible. But the deep sleep was inevitable, Rosetta's lander has slipped into hibernation after running its... Read More http://clicks.slashdot.org/ct.html?ufl=0&rtr=on&s=x8pb08,22wah,10sc,iaq7,ef6w,1yh,aqzj
Former Police Officer Indicted For Teaching How To Pass a Polygraph Test http://clicks.slashdot.org/ct.html?ufl=0&rtr=on&s=x8pb08,22wah,10sc,j6fh,abrg,1yh,aqzj
From the government-hates-competition department
George Maschke (699175) writes On Friday afternoon, the U.S. Department of Justice announced the indictment (2.6 mb PDF) of Douglas Gene Williams, a 69-year-old former Oklahoma City police polygraphist turned anti-polygraph activist for teaching... Read More http://clicks.slashdot.org/ct.html?ufl=0&rtr=on&s=x8pb08,22wah,10sc,kg1f,lf6a,1yh,aqzj
Comcast Kisses-Up To Obama, Publicly Agrees On Net Neutrality http://clicks.slashdot.org/ct.html?ufl=0&rtr=on&s=x8pb08,22wah,10sc,cewx,cg82,1yh,aqzj
From the wormtongues-all-around department
MojoKid writes Comcast is one of two companies to have earned Consumerist's "Worst Company in America" title on more than one occasion and it looks like they're lobbying for a third title. That is, unless there's another explanation as to how the... Read More http://clicks.slashdot.org/ct.html?ufl=0&rtr=on&s=x8pb08,22wah,10sc,gakt,jpmo,1yh,aqzj
Ask Slashdot: Programming Education Resources For a Year Offline? http://clicks.slashdot.org/ct.html?ufl=0&rtr=on&s=x8pb08,22wah,10sc,i2z2,j2ja,1yh,aqzj
From the maybe-a-local-phrasebook department
An anonymous reader writes "I will be traveling to a remote Himalayan village for year and won't have access to the internet. What offline resources would you all recommend to help me continue to develop my coding skills? I think this would be a... Read More http://clicks.slashdot.org/ct.html?ufl=0&rtr=on&s=x8pb08,22wah,10sc,dvj4,8dgh,1yh,aqzj
Alleged Satellite Photo Says Ukraine Shootdown of MH17 http://clicks.slashdot.org/ct.html?ufl=0&rtr=on&s=x8pb08,22wah,10sc,6amg,ehfi,1yh,aqzj
From the if-the-glove-won't-fit department
theshowmecanuck (703852) writes A group calling itself the Russian Union of Engineers has published a photograph, picked up by many news organizations (just picked one, Google it yourself to find more), claiming to show that MH17 was shot down by... Read More http://clicks.slashdot.org/ct.html?ufl=0&rtr=on&s=x8pb08,22wah,10sc,kx21,15cu,1yh,aqzj
US DOE Sets Sights On 300 Petaflop Supercomputer http://clicks.slashdot.org/ct.html?ufl=0&rtr=on&s=x8pb08,22wah,10sc,9b4x,5y5d,1yh,aqzj
From the who-is-this-we-paleface? department
dcblogs writes U.S. officials Friday announced plans to spend $325 million on two new supercomputers, one of which may eventually be built to support speeds of up to 300 petaflops. The U.S. Department of Energy, the major funder of supercomputers... Read More http://clicks.slashdot.org/ct.html?ufl=0&rtr=on&s=x8pb08,22wah,10sc,92u4,310d,1yh,aqzj
Ask Slashdot: Who's the Doctors Without Borders of Technology? http://clicks.slashdot.org/ct.html?ufl=0&rtr=on&s=x8pb08,22wah,10sc,7gbu,25op,1yh,aqzj
From the trespassers-mostly department
danspalding writes I'm transitioning into full time tech work after 10 years in education. To that end, after years of tooling around with command line and vim, I'm starting a programming bootcamp in early December. I used to think I wanted to go... Read More http://clicks.slashdot.org/ct.html?ufl=0&rtr=on&s=x8pb08,22wah,10sc,blvv,egxy,1yh,aqzj
Entrepreneur Injects Bitcoin Wallets Into Hands http://clicks.slashdot.org/ct.html?ufl=0&rtr=on&s=x8pb08,22wah,10sc,g9t3,i8da,1yh,aqzj
From the heirs-are-not-amused department
wiredmikey writes A Dutch entrepreneur has had two microchips containing Bitcoin injected into his hands to help him make contactless payments. The chips, enclosed in a 2mm by 12mm capsule of "biocompatible" glass, were injected using a special... Read More http://clicks.slashdot.org/ct.html?ufl=0&rtr=on&s=x8pb08,22wah,10sc,73v6,1zki,1yh,aqzj
Microsoft Aims To Offer Windows 10 Upgrades For All Windows Phone 8 Lumias http://clicks.slashdot.org/ct.html?ufl=0&rtr=on&s=x8pb08,22wah,10sc,ad3c,5wfu,1yh,aqzj
From the number-by-any-other-number department
An anonymous reader writes News suggesting that Microsoft plans to offer Windows 10 upgrades for all its Windows Phone 8 devices broke today. "It's our intention to enable a Windows 10 upgrade for Lumia Windows Phone 8 smartphones," a Microsoft... Read More http://clicks.slashdot.org/ct.html?ufl=0&rtr=on&s=x8pb08,22wah,10sc,ebtb,le5x,1yh,aqzj
R. A. Montgomery, Creator of the "Choose Your Own Adventure" Books, Dead At 78 http://clicks.slashdot.org/ct.html?ufl=0&rtr=on&s=x8pb08,22wah,10sc,jbbx,7g6y,1yh,aqzj
From the your-codename-is-jonah department
Dave Knott writes Raymond Almiran Montgomery, original publisher and author of the incredibly popular "Choose Your Own Adventure" book series for children, the 4th bestselling children's series of all time, has died at the age of 78. In 1975,... Read More http://clicks.slashdot.org/ct.html?ufl=0&rtr=on&s=x8pb08,22wah,10sc,5jp2,a7ls,1yh,aqzj
Real Steampunk Computer Brought Back To Life http://clicks.slashdot.org/ct.html?ufl=0&rtr=on&s=x8pb08,22wah,10sc,g7nv,eiak,1yh,aqzj
From the malware-free department
New submitter engineerguy writes We discovered a 100 year old 19th century computer that does Fourier analysis with just gears spring and levers. It was locked in a glass case at the University of Illinois Department of Mathematics. We rebuilt a... Read More http://clicks.slashdot.org/ct.html?ufl=0&rtr=on&s=x8pb08,22wah,10sc,g887,1slz,1yh,aqzj
AT&T Stops Using 'Super Cookies' To Track Cellphone Data http://clicks.slashdot.org/ct.html?ufl=0&rtr=on&s=x8pb08,22wah,10sc,gxkh,d3ck,1yh,aqzj
From the turns-out-people-hate-that department
jriding (1076733) writes AT&T Mobility, the nation's second-largest cellular provider, says it's no longer attaching hidden Internet tracking codes to data transmitted from its users' smartphones. The practice made it nearly impossible to... Read More http://clicks.slashdot.org/ct.html?ufl=0&rtr=on&s=x8pb08,22wah,10sc,9145,j9mq,1yh,aqzj
New Trial Brings Skype to (Some) Browsers http://clicks.slashdot.org/ct.html?ufl=0&rtr=on&s=x8pb08,22wah,10sc,11f1,e887,1yh,aqzj
From the video-chat-not-yet-standard-browser-feature department
Ars Technica reports that Microsoft has begun giving some users a taste of a new version of Skype, with a big difference compared to previous ones: the new one (tested by users on an invitation basis) is browser based. Rather than using the... Read More http://clicks.slashdot.org/ct.html?ufl=0&rtr=on&s=x8pb08,22wah,10sc,f7r7,ffwo,1yh,aqzj
See all today's stories - http://clicks.slashdot.org/ct.html?ufl=0&rtr=on&s=x8pb08,22wah,10sc,lczi,3ou1,1yh,aqzj
Submit a Story to Slashdot! http://clicks.slashdot.org/ct.html?ufl=0&rtr=on&s=x8pb08,22wah,10sc,ezuv,f7p0,1yh,aqzj
Follow us on:
Facebook - http://clicks.slashdot.org/ct.html?ufl=0&rtr=on&s=x8pb08,22wah,10sc,k3xq,iu97,1yh,aqzj
Twitter - http://clicks.slashdot.org/ct.html?ufl=0&rtr=on&s=x8pb08,22wah,10sc,hhbe,5104,1yh,aqzj
Google+ - http://clicks.slashdot.org/ct.html?ufl=0&rtr=on&s=x8pb08,22wah,10sc,lho1,copu,1yh,aqzj
__________________________________________________________________________
You are subscribed to this Resource Newsletter as habeus@stalphonsos.com .
To change your preferences - receive this in html or text, visit the Preference Center!
http://clicks.slashdot.org/ct.html?ufl=0&rtr=on&s=x8pb08,22wah,10sc,m454,24ky,1yh,aqzj&EMAIL_ADDRESS=habeus@stalphonsos.com
To unsubscribe, send an email to: unsubscribe-47676@elabs10.com
Slashdot | 594 Howard Street, Suite 300 | San Francisco, CA 94105
To view our Privacy Policy click here: http://clicks.slashdot.org/ct.html?ufl=0&rtr=on&s=x8pb08,22wah,10sc,8pii,7uiv,1yh,aqzj