AFS-PAG

 view release on metacpan or  search on metacpan

.gitignore  view on Meta::CPAN

/Build
/MANIFEST.bak
/MYMETA.json
/MYMETA.yml
/_build/
/blib/
/config.log
/cover_db
/glue/
/lib/AFS/PAG.c
*.o

Build.PL  view on Meta::CPAN

#!/usr/bin/perl
#
# Build script for the AFS::PAG distribution.
#
# Written by Russ Allbery <rra@cpan.org>
# Copyright 2013, 2014
#     The Board of Trustees of the Leland Stanford Junior University
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
# DEALINGS IN THE SOFTWARE.

use 5.010;
use autodie;
use strict;
use warnings;

use Config::AutoConf;
use File::Basename qw(basename);
use File::Path qw(remove_tree);
use File::Spec;
use Module::Build;

# Check whether it's possible to link a program that uses a particular
# function.  This is written like a Config::AutoConf method and should ideally
# be incorporated into that module.  This macro caches its result in the
# ac_cv_func_FUNCTION variable.
#
# $self         - The Config::AutoConf state object
# $function     - The function to check for
# $found_ref    - Code reference to call if the function was found
# $notfound_ref - Code reference to call if the function wasn't found
#
# Returns: True if the function was found, false otherwise
sub check_func {
    my ($self, $function, $found_ref, $notfound_ref) = @_;
    $self = $self->_get_instance();

    # Build the name of the cache variable.
    my $cache_name = $self->_cache_name('func', $function);

    # Wrap the actual check in a closure so that we can use check_cached.
    my $check_sub = sub {
        my $have_func = $self->link_if_else($self->lang_call(q{}, $function));
        if ($have_func) {
            if (defined($found_ref) && ref($found_ref) eq 'CODE') {
                $found_ref->();
            }
        } else {
            if (defined($notfound_ref) && ref($notfound_ref) eq 'CODE') {
                $notfound_ref->();
            }
        }
        return $have_func;
    };

    # Run the check and cache the results.
    return $self->check_cached($cache_name, "for $function", $check_sub);
}

# The same as check_func, but takes a list of functions to look for and checks
# for each in turn.  Define HAVE_FUNCTION for each function that was found,
# and also run the $found_ref code each time a function was found.  Run the
# $notfound_ref code each time a function wasn't found.  Both code references
# are passed the name of the function that was found.
#
# $self          - The Config::AutoConf state object
# $functions_ref - Reference to an array of functions to check for
# $found_ref     - Code reference to call if a function was found
# $notfound_ref  - Code reference to call if a function wasn't found
#
# Returns: True if all functions were found, false otherwise.
sub check_funcs {
    my ($self, $functions_ref, $user_found_ref, $user_notfound_ref) = @_;
    $self = $self->_get_instance();

    # Build the code reference to run when a function was found.  This defines
    # a HAVE_FUNCTION symbol, plus runs the current $found_ref if there is
    # one.
    my $func_found_ref = sub {
        my ($function) = @_;

        # Generate the name of the symbol we'll define.
        my $have_func_name = 'HAVE_' . uc($function);
        $have_func_name =~ tr/_A-Za-z0-9/_/c;

        # Define the symbol.
        $self->define_var($have_func_name, 1,
            "Defined when $function is available");

        # Run the user-provided hook, if there is one.
        if (defined($user_found_ref) && ref($user_found_ref) eq 'CODE') {
            $user_found_ref->($function);
        }
    };

    # Go through the list of functions and call check_func for each one.  We
    # generate new closures for the found and not-found functions that pass in
    # the relevant function name.
    my $return = 1;
    for my $function (@{$functions_ref}) {
        my $found_ref    = sub { $func_found_ref->($function) };
        my $notfound_ref = sub { $user_notfound_ref->($function) };
        $return &= check_func($self, $function, $found_ref, $notfound_ref);
    }
    return $return;
}

# Returns C code that includes the given headers.  Used to construct prologues
# for check functions.
#
# @headers - The headers to include
#
# Returns: C source as a string that includes those headers
sub include {
    my @headers = @_;
    my $result  = q{};
    for my $header (@headers) {
        $result .= "#include <$header>\n";
    }
    return $result;
}

# Probes the C compilation environment for the information required to build
# the embedded libkafs compatibility layer.  This should be a Perl equivalent
# of the m4/kafs.m4 Autoconf macros from rra-c-util, plus the additional
# probes needed for the compatibility layer for building the cod.  Writes the
# results to glue/config.h and returns a list of extra C files to add to the
# module build.
#
# $build - The module build object, used to add additional libraries
#
# Returns: List of extra directories to add to the module build
#  Throws: Text exception if the module cannot be built in this environment
sub config_kafs {
    my ($build) = @_;
    my $config = Config::AutoConf->new;

    # Checks needed for the generic portability layer.
    $config->check_default_headers;
    if (!$config->check_header('stdbool.h')) {
        $config->check_type('_Bool');
    }
    $config->check_type('sig_atomic_t', undef, undef,
        include(qw(sys/types.h signal.h)));
    $config->check_type('ssize_t', undef, undef, include('sys/types.h'));

    # Checks needed by all libkafs code.
    $config->check_header('sys/ioccom.h');

    # If the user passed extra flags into Build.PL, use them for probes.
    if ($build->extra_linker_flags) {
        my $flags = $build->extra_linker_flags;
        my @flags = ref($flags) ? @{$flags} : ($flags);
        $config->push_link_flags(@flags);
    }

    # Check if we have a library available to us.  If so, check whether it
    # provides k_pioctl and k_haspag and then return.
    my $lib = $config->search_libs('k_hasafs', ['kafs', 'kopenafs']);
    my @files;
    if ($lib) {
        $config->define_var('HAVE_K_HASAFS', 1,
            'Define to 1 if you have the k_hasafs function.');
        my $flags = $build->extra_linker_flags;
        my @flags = ref($flags) ? @{$flags} : ($flags);
        $build->extra_linker_flags(@flags, '-l' . $lib);
        if ($lib eq 'kafs') {
            $config->check_header('kafs.h');
        } elsif ($lib eq 'kopenafs') {
            $config->check_header('kopenafs.h');
        }
        check_funcs($config, ['k_pioctl']);
        if (!check_funcs($config, ['k_haspag'])) {
            @files = qw(portable/k_haspag.c);
        }
    } else {
        @files = qw(kafs/kafs.c portable/k_haspag.c);
        $config->define_var('HAVE_KAFS_REPLACEMENT', 1,
            'Define to 1 if the libkafs replacement is built.');
        $config->define_var('HAVE_KAFS_LINUX', 1,
            'Define to 1 to use the Linux AFS /proc interface.');
    }

    # Write out the configuration.
    $config->write_config_h('glue/config.h');

    # Return the list of files to add to the build.
    return @files;
}

# Basic package configuration.
my $build = Module::Build->new(
    module_name          => 'AFS::PAG',
    dist_version_from    => 'lib/AFS/PAG.pm',
    dist_author          => 'Russ Allbery <rra@cpan.org>',
    license              => 'mit',
    recursive_test_files => 1,
    add_to_cleanup       => [qw(config.log cover_db glue/*.o)],

    # XS configuration.
    c_source             => 'glue',
    extra_compiler_flags => ['-I.'],

    # Additional package metadata.
    meta_merge => {
        resources => {
            repository => 'git://git.eyrie.org/afs/afs-pag.git',
            bugtracker =>
              'https://rt.cpan.org/Public/Dist/Display.html?Name=AFS-PAG',
        },
    },

    # Other package relationships.
    configure_requires => {
        'Config::AutoConf' => 0,
        'Module::Build'    => '0.28',
        autodie            => 0,
        perl               => '5.010',
    },
    requires => {
        autodie => 0,
        perl    => '5.010',
    },
);

# Create the directory that will be used for config.h and stub files.
remove_tree('glue');
mkdir('glue');

# Write out the config.h file and get the list of files to add to the build.
my @c_files = config_kafs($build);

# We can't just add the C source files directly to the build for a couple of
# reasons.  First, Perl ships its own config.h, so we need to be sure we
# include our own instead of Perl's before building any source, since all of
# the files (copied from rra-c-util, so we don't want to change them) include
# config.h as the first action.  Second, Module::Build can only handle one
# directory of supplemental source files.
#
# We deal with both of these issues by creating stub files in a subdirectory
# named glue that include glue/config.h and then the actual C source file.
for my $file (@c_files) {
    my $glue_file = File::Spec->catfile('glue', basename($file));
    open(my $wrapper, '>', $glue_file);
    say {$wrapper} '#include <glue/config.h>'
      or die "Cannot write to $glue_file: $!\n";
    say {$wrapper} "#include <$file>"
      or die "Cannot write to $glue_file: $!\n";
    close($wrapper);
}

# Generate the build script.
$build->create_build_script;

Changes  view on Meta::CPAN

                      User-Visible AFS::PAG Changes

AFS::PAG 1.02 (2014-07-27)

    Rename NEWS to Changes to match the normal Perl convention.

    Add repository and bugtracker information in the distribution
    metadata.

    Update to rra-c-util 5.5:

    * Use Lancaster Consensus environment variables to control tests.
    * Work around perltidy bug that leaves behind stray log files.
    * Use calloc or reallocarray for protection against integer overflows.

AFS::PAG 1.01 (2013-10-06)

    Define the correct preprocessor symbols to build properly if a libkafs
    or libkopenafs library was found.

    Mark autodie required for configure and use for correct automated
    testing behavior on Perl 5.10.0.  (autodie was added to core in
    5.10.1.)

AFS::PAG 1.00 (2013-09-12)

    Initial public release with support for libkafs, libkopenafs, and
    Linux systems with no support library.  pioctl is not yet supported,
    only hasafs, haspag, setpag, and unlog.  The build system has only
    been tested on Debian.

LICENSE  view on Meta::CPAN

Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Comment: This file documents the copyright statements and licenses for
 every file in this package in a machine-readable format.  For a less
 detailed, higher-level overview, see README.
 .
 For any copyright year range specified as YYYY-ZZZZ in this file, the
 range specifies every single year in that closed interval.
Copyright: 2013 The Board of Trustees of the Leland Stanford Junior University
License: Expat

Files: *
Copyright: 2006-2014
    The Board of Trustees of the Leland Stanford Junior University
License: Expat
 Permission is hereby granted, free of charge, to any person obtaining a
 copy of this software and associated documentation files (the
 "Software"), to deal in the Software without restriction, including
 without limitation the rights to use, copy, modify, merge, publish,
 distribute, sublicense, and/or sell copies of the Software, and to permit
 persons to whom the Software is furnished to do so, subject to the
 following conditions:
 .
 The above copyright notice and this permission notice shall be included
 in all copies or substantial portions of the Software.
 .
 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
 OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
 THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Files: kafs/sys-syscall.c portable/k_haspag.c portable/macros.h
 portable/stdbool.h portable/system.h
Copyright: no copyright notice, see License
License: rra-public-domain
 The authors hereby relinquish any claim to any copyright that they may
 have in this work, whether granted under contract or by operation of law
 or international treaty, and hereby commit to the public, at large, that
 they shall not, at any time in the future, seek to enforce any copyright
 in this work against any person or entity, or prevent any person or
 entity from copying, publishing, distributing or creating derivative
 works of this work.

MANIFEST  view on Meta::CPAN

.gitignore
Build.PL
Changes
kafs/kafs.c
kafs/sys-darwin10.c
kafs/sys-darwin8.c
kafs/sys-linux.c
kafs/sys-solaris.c
kafs/sys-syscall.c
lib/AFS/PAG.pm
lib/AFS/PAG.xs
LICENSE
MANIFEST			This list of files
MANIFEST.SKIP
portable/k_haspag.c
portable/kafs.h
portable/macros.h
portable/stdbool.h
portable/system.h
README
t/data/perl.conf
t/data/perlcriticrc
t/data/perltidyrc
t/docs/pod-coverage.t
t/docs/pod-spelling.t
t/docs/pod.t
t/docs/synopsis.t
t/lib/Test/RRA.pm
t/lib/Test/RRA/Config.pm
t/pag/basic.t
t/pag/isolation.t
t/style/coverage.t
t/style/critic.t
t/style/minimum-version.t
t/style/strict.t
TODO
META.yml
META.json

MANIFEST.SKIP  view on Meta::CPAN

# -*- conf -*-

# Avoid version control files.
^\.git/

# Avoid generated build files.
\bblib/
^config\.log$
^glue/
^lib/AFS/PAG\.c$
\.o$

# Avoid Module::Build generated and utility files.
\bBuild$
\b_build/
\bBuild.bat$
\bBuild.COM$
\bBUILD.COM$
\bbuild.com$

# Avoid temp and backup files.
~$
\.old$
\#$
\b\.#
\.bak$
\.tmp$
\.#
\.rej$

# Avoid OS-specific files/dirs
# Mac OSX metadata
\B\.DS_Store
# Mac OSX SMB mount metadata files
\B\._

# Avoid Devel::Cover and Devel::CoverX::Covered files.
\bcover_db\b
\bcovered\b

# Avoid MYMETA files
^MYMETA\.

# Avoid archives of this distribution
\bAFS-PAG-[\d\.\_]+

META.json  view on Meta::CPAN

{
   "abstract" : "Perl bindings for AFS PAG manipulation",
   "author" : [
      "Russ Allbery <rra@cpan.org>"
   ],
   "dynamic_config" : 1,
   "generated_by" : "Module::Build version 0.4003, CPAN::Meta::Converter version 2.120921",
   "license" : [
      "mit"
   ],
   "meta-spec" : {
      "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec",
      "version" : "2"
   },
   "name" : "AFS-PAG",
   "prereqs" : {
      "build" : {
         "requires" : {
            "ExtUtils::CBuilder" : "0"
         }
      },
      "configure" : {
         "requires" : {
            "Config::AutoConf" : "0",
            "Module::Build" : "0.28",
            "autodie" : "0",
            "perl" : "5.010"
         }
      },
      "runtime" : {
         "requires" : {
            "autodie" : "0",
            "perl" : "5.010"
         }
      }
   },
   "provides" : {
      "AFS::PAG" : {
         "file" : "lib/AFS/PAG.pm",
         "version" : "1.02"
      }
   },
   "release_status" : "stable",
   "resources" : {
      "bugtracker" : {
         "web" : "https://rt.cpan.org/Public/Dist/Display.html?Name=AFS-PAG"
      },
      "license" : [
         "http://opensource.org/licenses/mit-license.php"
      ],
      "repository" : {
         "url" : "git://git.eyrie.org/afs/afs-pag.git"
      }
   },
   "version" : "1.02"
}

META.yml  view on Meta::CPAN

---
abstract: 'Perl bindings for AFS PAG manipulation'
author:
  - 'Russ Allbery <rra@cpan.org>'
build_requires:
  ExtUtils::CBuilder: 0
configure_requires:
  Config::AutoConf: 0
  Module::Build: 0.28
  autodie: 0
  perl: 5.010
dynamic_config: 1
generated_by: 'Module::Build version 0.4003, CPAN::Meta::Converter version 2.120921'
license: mit
meta-spec:
  url: http://module-build.sourceforge.net/META-spec-v1.4.html
  version: 1.4
name: AFS-PAG
provides:
  AFS::PAG:
    file: lib/AFS/PAG.pm
    version: 1.02
requires:
  autodie: 0
  perl: 5.010
resources:
  bugtracker: https://rt.cpan.org/Public/Dist/Display.html?Name=AFS-PAG
  license: http://opensource.org/licenses/mit-license.php
  repository: git://git.eyrie.org/afs/afs-pag.git
version: 1.02

README  view on Meta::CPAN

                              AFS::PAG 1.02
                 (Perl bindings for AFS PAG manipulation)

                  Written by Russ Allbery <rra@cpan.org>

  Copyright 2013, 2014 The Board of Trustees of the Leland Stanford Junior
  University.  This software is distributed under a BSD-style license.
  Please see the section LICENSE below for more information.

BLURB

  AFS::PAG provides the standard PAG and token manipulation functions
  setpag and unlog to Perl programs as a native module.  It also provides
  the hasafs and haspag functions to detect whether AFS is running and
  whether the current process is in a PAG.  Unlike the more general AFS
  module, it will build with any recent OpenAFS, Heimdal's libkafs, or on
  Linux without any AFS libraries at all.

DESCRIPTION

  AFS is a distributed file system allowing cross-platform sharing of
  files among multiple computers.  It associates client credentials
  (called AFS tokens) with a Process Authentication Group, or PAG.
  AFS::PAG makes available in Perl the PAG manipulation functions provided
  by the libkafs or libkopenafs libraries.

  With the functions provided by this module, a Perl program can detect
  whether AFS is available on the local system and whether it is currently
  running inside a PAG.  It can also create a new PAG and put the current
  process in it, and remove any AFS tokens in the current PAG.

  This module doesn't provide a direct way to obtain new AFS tokens, only
  to create a new PAG so that any obtained tokens are isolated from other
  processes on the system and can be inherited by child processes.

REQUIREMENTS

  Perl 5.10.1 or later, the Config::AutoConf module, and a C compiler are
  required to build this module.  On any platform other than Linux, either
  the kafs library (from Heimdal) or the kopenafs library (from recent
  versions of OpenAFS) are also required.

  The following additional Perl modules will be used by the test suite if
  present:

      IPC::System::Simple
      Test::MinimumVersion
      Test::Perl::Critic
      Test::Pod
      Test::Pod::Coverage
      Test::Spelling
      Test::Strict
      Test::Synopsis

  All are available on CPAN.  Those tests will be skipped if the modules
  are not available.

  To enable tests that may be sensitive to the local environment or that
  produce a lot of false positives without uncovering many problems, set
  RRA_MAINTAINER_TESTS to a true value.

BUILDING AND INSTALLATION

  AFS::PAG uses Module::Build and can be installed using the same process
  as any other Module::Build module:

      perl Build.PL
      ./Build
      ./Build test
      ./Build install

  If your libkafs or libkopenafs libraries are in a path that's not
  searched by your linker by default, pass them to Build.PL using the
  --extra-linker-flags option, as in:

      perl Build.PL --extra-linker-flags '-L/opt/openafs/lib'

  You will have to run the last command as root unless you're installing
  into a local Perl module tree in your home directory.

SUPPORT

  The AFS::PAG web page at:

      http://www.eyrie.org/~eagle/software/afs-pag/

  will always have the current version of this package, the current
  documentation, and pointers to any additional resources.

  For bug tracking, this package uses the CPAN bug tracker at:

      https://rt.cpan.org/Public/Dist/Display.html?Name=AFS-PAG

  I welcome bug reports and patches for this package at rra@cpan.org or
  via the CPAN bug tracker.  However, please be aware that I tend to be
  extremely busy and work projects often take priority.  I'll save your
  mail and get to it as soon as I can, but it may take me a couple of
  months.

SOURCE REPOSITORY

  AFS::PAG is maintained using Git.  You can access the current source by
  cloning the repository at:

      git://git.eyrie.org/afs/afs-pag.git

  or view the repository via the web at:

      http://git.eyrie.org/?p=afs/afs-pag.git

  When contributing modifications, either patches (possibly generated by
  git format-patch) or Git pull requests are welcome.

LICENSE

  The AFS::PAG package as a whole is covered by the following copyright
  statement and license:

    Copyright 2013, 2014
        The Board of Trustees of the Leland Stanford Junior University

    Permission is hereby granted, free of charge, to any person obtaining
    a copy of this software and associated documentation files (the
    "Software"), to deal in the Software without restriction, including
    without limitation the rights to use, copy, modify, merge, publish,
    distribute, sublicense, and/or sell copies of the Software, and to
    permit persons to whom the Software is furnished to do so, subject to
    the following conditions:
    
    The above copyright notice and this permission notice shall be
    included in all copies or substantial portions of the Software.
    
    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
    IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
    CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
    TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
    SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

  All individual files without an explicit exception below are released
  under this license.  Some files may have additional copyright holders as
  noted in those files.  There is detailed information about the licensing
  of each file in the LICENSE file in this distribution.

  Some files in this distribution are individually released under
  different licenses, all of which are compatible with the above general
  package license but which may require preservation of additional
  notices.  All required notices are preserved in the LICENSE file.

TODO  view on Meta::CPAN

                           AFS::PAG To-Do List

API:

 * Expose pioctl and find a good way to let callers use it.  This will
   require some way of constructing the pioctl call number and arguments
   from inside Perl, or at least some documented guidance as to how to use
   pack.

Build:

 * Add config.guess and support the libkafs replacement for the other
   operating systems on which it works.  (Mac OS X, Solaris, and other
   system-call-only platforms.)

 * Add the necessary probes to link with OpenAFS libraries on AIX and
   IRIX.

 * Contribute back support for check_func to Config::AutoConf to clean up
   the code in Build.PL.

 * Honor all of the build settings passed to Module::Build when doing
   probes with Config::AutoConf.  This will probably require pulling the
   ExtUtils::CBuilder object from Module::Build and modifying
   Config::AutoConf to use the same builder.

kafs/kafs.c  view on Meta::CPAN

/*
 * kafs replacement, main API.
 *
 * This is a simple implementation of the k_hasafs, k_setpag, and k_unlog
 * functions.  It is for use on systems that don't have libkafs or
 * libkopenafs, or where a dependency on those libraries is not desirable for
 * some reason.
 *
 * A more robust implementation of the full kafs interface would have a
 * separate header file with the various system call constants and would
 * support more operations and the k_pioctl interface.  Since this is a
 * stripped-down implementation with only the few functions to do PAG
 * management, various interface constants and system call numbers are
 * hard-coded here.
 *
 * The canonical version of this file is maintained in the rra-c-util package,
 * which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>.
 *
 * Written by Russ Allbery <eagle@eyrie.org>
 * Copyright 2006, 2007, 2009
 *     The Board of Trustees of the Leland Stanford Junior University
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 */

#include <config.h>
#include <portable/kafs.h>
#include <portable/system.h>

#include <errno.h>
#include <fcntl.h>
#include <signal.h>
#ifdef HAVE_SYS_IOCCOM_H
# include <sys/ioccom.h>
#endif
#include <sys/ioctl.h>
#include <sys/stat.h>

/* Used for unused parameters to silence gcc warnings. */
#define UNUSED __attribute__((__unused__))

/* Provided by the relevant sys-*.c file. */
static int k_syscall(long, long, long, long, long, int *);

/*
 * Include the syscall implementation for this host, based on the configure
 * results.  An include of the C source is easier to handle in the build
 * machinery than lots of Automake conditionals.
 *
 * The included file must provide a k_syscall implementation.
 */
#if defined(HAVE_KAFS_DARWIN8)
# include <kafs/sys-darwin8.c>
#elif defined(HAVE_KAFS_DARWIN10)
# include <kafs/sys-darwin10.c>
#elif defined(HAVE_KAFS_LINUX)
# include <kafs/sys-linux.c>
#elif defined(HAVE_KAFS_SOLARIS)
# include <kafs/sys-solaris.c>
#elif defined(HAVE_KAFS_SYSCALL)
# include <kafs/sys-syscall.c>
#else
# error "Unknown AFS system call implementation"
#endif

/*
 * On some platforms, k_hasafs needs to try a system call.  This attempt may
 * fail with SIGSYS.  We therefore set a signal handler that changes a static
 * variable if SIGSYS is received.
 *
 * It's really ugly to do this in library or PAM module in so many ways.
 * Static variables are evil, changing signal handlers out from under an
 * application is evil, and the interaction of signals and threads is probably
 * nasty.  The only things that make this better is that this case will never
 * be triggered in the normal case of AFS being loaded and the only time that
 * we change this static variable is to say that the call failed, so there
 * shouldn't be a collision of updates from multiple calls.
 *
 * It's probably safe to just ignore SIGSYS instead, but this feels more
 * thorough.
 */
static volatile sig_atomic_t syscall_okay = 1;


/*
 * Signal handler to catch failed system calls and change the okay flag.
 */
#ifdef SIGSYS
static void
sigsys_handler(int s UNUSED)
{
    syscall_okay = 0;
    signal(SIGSYS, sigsys_handler);
}
#endif /* SIGSYS */


/*
 * The other system calls are implemented in terms of k_pioctl.  This
 * interface assumes that all pointers can be represented in a long, but then
 * so does the whole AFS system call interface.
 */
int
k_pioctl(char *path, int cmd, struct ViceIoctl *cmarg, int follow)
{
    int err, rval;

    rval = k_syscall(20, (long) path, cmd, (long) cmarg, follow, &err);
    if (rval != 0)
        err = rval;
    return err;
}


/*
 * Probe to see if AFS is available and we can make system calls successfully.
 * This just attempts the set token system call with an empty token structure,
 * which will be a no-op in the kernel.
 */
int
k_hasafs(void)
{
    struct ViceIoctl iob;
    int rval, saved_errno, okay;
    void (*saved_func)(int);

    saved_errno = errno;

#ifdef SIGSYS
    saved_func = signal(SIGSYS, sigsys_handler);
#endif

    iob.in = NULL;
    iob.in_size = 0;
    iob.out = NULL;
    iob.out_size = 0;
    rval = k_pioctl(NULL, _IOW('V', 3, struct ViceIoctl), &iob, 0);

#ifdef SIGSYS
    signal(SIGSYS, saved_func);
#endif

    okay = (syscall_okay && rval == -1 && errno == EINVAL);
    errno = saved_errno;
    return okay;
}


/*
 * The setpag system call.  This is special in that it's not a pioctl;
 * instead, it's a separate system call done directly through the afs_syscall
 * function.
 */
int
k_setpag(void)
{
    int err, rval;

    rval = k_syscall(21, 0, 0, 0, 0, &err);
    if (rval != 0)
        err = rval;
    return err;
}


/*
 * The unlog system call.  This destroys any tokens in the current PAG.
 */
int
k_unlog(void)
{
    struct ViceIoctl iob;

    iob.in = NULL;
    iob.in_size = 0;
    iob.out = NULL;
    iob.out_size = 0;
    return k_pioctl(NULL, _IOW('V', 9, struct ViceIoctl), &iob, 0);
}

kafs/sys-darwin10.c  view on Meta::CPAN

/*
 * AFS system call for Mac OS X 10.6 systems (and later).
 *
 * This is an AFS system call implementation for Mac OS X 10.6 systems (and
 * later).  It is for use on systems that don't have libkafs or libkopenafs,
 * or where a dependency on those libraries is not desirable for some reason.
 *
 * This file is included by kafs/kafs.c on Mac OS X 10.6 platforms and
 * therefore doesn't need its own copy of standard includes, only whatever
 * additional data is needed for the Linux interface.
 *
 * The canonical version of this file is maintained in the rra-c-util package,
 * which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>.
 *
 * Written by Russ Allbery <eagle@eyrie.org>
 * Copyright 2006, 2007, 2009, 2010, 2011
 *     The Board of Trustees of the Leland Stanford Junior University
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 */

/*
 * The struct passed to ioctl to do an AFS system call.  Definition taken from
 * the afs/afs_args.h OpenAFS header.  We choose one of two structs depending
 * on whether we have a 32-bit or 64-bit interface.  user_addr_t should be
 * provided by sys/types.h on Mac OS X.
 */
struct afssysargs {
    unsigned int syscall;
    unsigned int param1;
    unsigned int param2;
    unsigned int param3;
    unsigned int param4;
    unsigned int param5;
    unsigned int param6;
    unsigned int retval;
};
struct afssysargs64 {
    user_addr_t param1;
    user_addr_t param2;
    user_addr_t param3;
    user_addr_t param4;
    user_addr_t param5;
    user_addr_t param6;
    unsigned int syscall;
    unsigned int retval;
};


/*
 * The workhorse function that does the actual system call.  All the values
 * are passed as longs to match the internal OpenAFS interface, which means
 * that there's all sorts of ugly type conversion happening here.
 *
 * Returns -1 and sets errno to ENOSYS if attempting a system call fails and 0
 * otherwise.  If the system call was made, its return status will be stored
 * in rval.
 */
static int
k_syscall(long call, long param1, long param2, long param3, long param4,
          int *rval)
{
    int fd, code, oerrno;

    fd = open("/dev/openafs_ioctl", O_RDWR);
    if (fd < 0) {
        errno = ENOSYS;
        return -1;
    }

    if (sizeof(param1) == 8) {
        struct afssysargs64 syscall_data;

        syscall_data.syscall = call;
        syscall_data.param1 = param1;
        syscall_data.param2 = param2;
        syscall_data.param3 = param3;
        syscall_data.param4 = param4;
        syscall_data.param5 = 0;
        syscall_data.param6 = 0;
        code = ioctl(fd, _IOWR('C', 2, struct afssysargs64), &syscall_data);
        if (code == 0)
            *rval = syscall_data.retval;
    } else {
        struct afssysargs syscall_data;

        syscall_data.syscall = call;
        syscall_data.param1 = param1;
        syscall_data.param2 = param2;
        syscall_data.param3 = param3;
        syscall_data.param4 = param4;
        syscall_data.param5 = 0;
        syscall_data.param6 = 0;
        code = ioctl(fd, _IOWR('C', 1, struct afssysargs), &syscall_data);
        if (code == 0)
            *rval = syscall_data.retval;
    }

    oerrno = errno;
    close(fd);
    errno = oerrno;
    return code;
}

kafs/sys-darwin8.c  view on Meta::CPAN

/*
 * AFS system call for Mac OS X 10.4 and 10.5 systems.
 *
 * This is an AFS system call implementation for Mac OS X 10.4 and 10.5
 * systems only.  It is for use on systems that don't have libkafs or
 * libkopenafs, or where a dependency on those libraries is not desirable for
 * some reason.  For Mac OS X 10.6 and later, don't use this interface; it
 * doesn't correctly handle mixed 32-bit and 64-bit systems.
 *
 * This file is included by kafs/kafs.c on Mac OS X 10.4 and 10.5 platforms
 * and therefore doesn't need its own copy of standard includes, only whatever
 * additional data is needed for the Linux interface.
 *
 * The canonical version of this file is maintained in the rra-c-util package,
 * which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>.
 *
 * Written by Russ Allbery <eagle@eyrie.org>
 * Copyright 2006, 2007, 2009, 2010
 *     The Board of Trustees of the Leland Stanford Junior University
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 */

/*
 * The struct passed to ioctl to do an AFS system call.  Definition taken from
 * the afs/afs_args.h OpenAFS header.
 */
struct afssysargs {
    unsigned int syscall;
    unsigned int param1;
    unsigned int param2;
    unsigned int param3;
    unsigned int param4;
    unsigned int param5;
    unsigned int param6;
    unsigned int retval;
};


/*
 * The workhorse function that does the actual system call.  All the values
 * are passed as longs to match the internal OpenAFS interface, which means
 * that there's all sorts of ugly type conversion happening here.
 *
 * Returns -1 and sets errno to ENOSYS if attempting a system call fails and 0
 * otherwise.  If the system call was made, its return status will be stored
 * in rval.
 */
static int
k_syscall(long call, long param1, long param2, long param3, long param4,
          int *rval)
{
    struct afssysargs syscall_data;
    int fd, code, oerrno;

    fd = open("/dev/openafs_ioctl", O_RDWR);
    if (fd < 0) {
        errno = ENOSYS;
        return -1;
    }

    syscall_data.syscall = call;
    syscall_data.param1 = param1;
    syscall_data.param2 = param2;
    syscall_data.param3 = param3;
    syscall_data.param4 = param4;
    syscall_data.param5 = 0;
    syscall_data.param6 = 0;
    code = ioctl(fd, _IOWR('C', 1, struct afssysargs), &syscall_data);
    if (code == 0)
        *rval = syscall_data.retval;

    oerrno = errno;
    close(fd);
    errno = oerrno;
    return code;
}

kafs/sys-linux.c  view on Meta::CPAN

/*
 * AFS system call for Linux systems.
 *
 * This is an AFS system call implementation for Linux systems only (and new
 * enough implementations of OpenAFS on Linux that /proc/fs/openafs/afs_ioctl
 * exists).  It is for use on systems that don't have libkafs or libkopenafs,
 * or where a dependency on those libraries is not desirable for some reason.
 *
 * This file is included by kafs/kafs.c on Linux platforms and therefore
 * doesn't need its own copy of standard includes, only whatever additional
 * data is needed for the Linux interface.
 *
 * The canonical version of this file is maintained in the rra-c-util package,
 * which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>.
 *
 * Written by Russ Allbery <eagle@eyrie.org>
 * Copyright 2006, 2007, 2009
 *     The Board of Trustees of the Leland Stanford Junior University
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 */

/* 
 * The struct passed to ioctl to do an AFS system call.  Definition taken from
 * the afs/afs_args.h OpenAFS header.
 */
struct afsprocdata {
    long param4;
    long param3;
    long param2;
    long param1;
    long syscall;
};


/*
 * The workhorse function that does the actual system call.  All the values
 * are passed as longs to match the internal OpenAFS interface, which means
 * that there's all sorts of ugly type conversion happening here.
 *
 * The first path we attempt is the OpenAFS path; the second is the one used
 * by Arla (at least some versions).
 *
 * Returns -1 and sets errno to ENOSYS if attempting a system call fails and 0
 * otherwise.  If the system call was made, its return status will be stored
 * in rval.
 */
static int
k_syscall(long call, long param1, long param2, long param3, long param4,
          int *rval)
{
    struct afsprocdata syscall_data;
    int fd, oerrno;

    fd = open("/proc/fs/openafs/afs_ioctl", O_RDWR);
    if (fd < 0)
        fd = open("/proc/fs/nnpfs/afs_ioctl", O_RDWR);
    if (fd < 0) {
        errno = ENOSYS;
        return -1;
    }

    syscall_data.syscall = call;
    syscall_data.param1 = param1;
    syscall_data.param2 = param2;
    syscall_data.param3 = param3;
    syscall_data.param4 = param4;
    *rval = ioctl(fd, _IOW('C', 1, void *), &syscall_data);

    oerrno = errno;
    close(fd);
    errno = oerrno;
    return 0;
}

kafs/sys-solaris.c  view on Meta::CPAN

/*
 * AFS system call for Solaris 11 and later.
 *
 * This is an AFS system call implementation for Solaris 11 and later
 * (versions of Solaris where OpenAFS has switched from a system call to an
 * ioctl).  It is for use on systems that don't have libkafs or libkopenafs,
 * or where a dependency on those libraries is not desirable for some reason.
 *
 * This file is included by kafs/kafs.c on Solaris 11 platforms and therefore
 * doesn't need its own copy of standard includes, only whatever additional
 * data is needed for the Linux interface.
 *
 * The canonical version of this file is maintained in the rra-c-util package,
 * which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>.
 *
 * Written by Russ Allbery <eagle@eyrie.org>
 * Copyright 2006, 2007, 2009, 2010
 *     The Board of Trustees of the Leland Stanford Junior University
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 */

/*
 * The struct passed to ioctl to do an AFS system call.  Definition taken from
 * the afs/afs_args.h OpenAFS header.  We choose one of two structs depending
 * on whether we have a 32-bit or 64-bit interface.
 */
struct afssysargs {
    uint32_t param6;
    uint32_t param5;
    uint32_t param4;
    uint32_t param3;
    uint32_t param2;
    uint32_t param1;
    uint32_t syscall;
};
struct afssysargs64 {
    uint64_t param6;
    uint64_t param5;
    uint64_t param4;
    uint64_t param3;
    uint64_t param2;
    uint64_t param1;
    uint32_t syscall;
};


/*
 * The workhorse function that does the actual system call.  All the values
 * are passed as longs to match the internal OpenAFS interface, which means
 * that there's all sorts of ugly type conversion happening here.
 *
 * Returns -1 and sets errno to ENOSYS if attempting a system call fails and 0
 * otherwise.  If the system call was made, its return status will be stored
 * in rval.
 */
static int
k_syscall(long call, long param1, long param2, long param3, long param4,
          int *rval)
{
    int fd, code, oerrno, callnum;

#ifdef _ILP32
    struct afssysargs syscall_data;

    syscall_data.syscall = call;
    syscall_data.param1 = param1;
    syscall_data.param2 = param2;
    syscall_data.param3 = param3;
    syscall_data.param4 = param4;
    syscall_data.param5 = 0;
    syscall_data.param6 = 0;
    callnum = _IOW('C', 2, struct afssysargs);
#else
    struct afssysargs64 syscall_data;

    syscall_data.syscall = call;
    syscall_data.param1 = param1;
    syscall_data.param2 = param2;
    syscall_data.param3 = param3;
    syscall_data.param4 = param4;
    syscall_data.param5 = 0;
    syscall_data.param6 = 0;
    callnum = _IOW('C', 1, struct afssysargs64);
#endif

    fd = open("/dev/afs", O_RDWR);
    if (fd < 0) {
        errno = ENOSYS;
        return -1;
    }
    *rval = ioctl(fd, callnum, &syscall_data);

    oerrno = errno;
    close(fd);
    errno = oerrno;
    return 0;
}

kafs/sys-syscall.c  view on Meta::CPAN

/*
 * AFS system call via syscall.
 *
 * This is an AFS system call implementation for systems that use syscall,
 * such as Solaris prior to Solaris 11.  It is for use on systems that don't
 * have libkafs or libkopenafs, or where a dependency on those libraries is
 * not desirable for some reason.
 *
 * This file is included by kafs/kafs.c on platforms that use syscall and
 * therefore doesn't need its own copy of standard includes, only whatever
 * additional data is needed for the Linux interface.
 *
 * The canonical version of this file is maintained in the rra-c-util package,
 * which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>.
 *
 * Written by Russ Allbery <eagle@eyrie.org>
 *
 * The authors hereby relinquish any claim to any copyright that they may have
 * in this work, whether granted under contract or by operation of law or
 * international treaty, and hereby commit to the public, at large, that they
 * shall not, at any time in the future, seek to enforce any copyright in this
 * work against any person or entity, or prevent any person or entity from
 * copying, publishing, distributing or creating derivative works of this
 * work.
 */

#include <afs/param.h>
#include <sys/syscall.h>

int
k_syscall(long call, long param1, long param2, long param3, long param4,
          int *rval)
{
    *rval = syscall(AFS_SYSCALL, call, param1, param2, param3, param4);
    return 0;
}

lib/AFS/PAG.pm  view on Meta::CPAN

# Perl bindings for the PAG functions in libkafs.
#
# This is the Perl boostrap file for the AFS::PAG module, nearly all of which
# is implemented in XS.  For the actual source, see PAG.xs.  This file
# contains the bootstrap and export code and the documentation.
#
# Written by Russ Allbery <rra@cpan.org>
# Copyright 2013
#     The Board of Trustees of the Leland Stanford Junior University
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
# DEALINGS IN THE SOFTWARE.

package AFS::PAG;

use 5.008;
use strict;
use warnings;

use base qw(DynaLoader);

use Exporter qw(import);

our (@EXPORT_OK, $VERSION);

# Set all import-related variables in a BEGIN block for robustness.
BEGIN {
    @EXPORT_OK = qw(hasafs haspag setpag unlog);
    $VERSION   = '1.02';
}

# Load the binary module.
bootstrap AFS::PAG $VERSION;

1;
__END__

=for stopwords
Allbery AFS PAG libkafs libkopenafs Kerberos aklog UID kdestroy

=head1 NAME

AFS::PAG - Perl bindings for AFS PAG manipulation

=head1 SYNOPSIS

    use AFS::PAG qw(hasafs setpag unlog);

    if (hasafs()) {
        setpag();
        system('aklog') == 0
          or die "cannot get tokens\n";
        do_afs_things();
        unlog();
    }

=head1 DESCRIPTION

AFS is a distributed file system allowing cross-platform sharing of files
among multiple computers.  It associates client credentials (called AFS
tokens) with a Process Authentication Group, or PAG.  AFS::PAG makes
available in Perl the PAG manipulation functions provided by the libkafs
or libkopenafs libraries.

With the functions provided by this module, a Perl program can detect
whether AFS is available on the local system (hasafs()) and whether it is
currently running inside a PAG (haspag()).  It can also create a new PAG
and put the current process in it (setpag()) and remove any AFS tokens in
the current PAG (unlog()).

Note that this module doesn't provide a direct way to obtain new AFS
tokens.  Programs that need AFS tokens should normally obtain Kerberos
tickets (via whatever means) and then run the program B<aklog>, which
comes with most AFS distributions.  This program will create AFS tokens
from the current Kerberos ticket cache and store them in the current PAG.
To isolate those credentials from the rest of the system, call setpag()
before running B<aklog>.

=head1 FUNCTIONS

This module provides the following functions, none of which are exported
by default:

=over 4

=item hasafs()

Returns true if the local host is running an AFS client and false
otherwise.

=item haspag()

Returns true if the current process is running inside a PAG and false
otherwise.  AFS tokens obtained outside of a PAG are visible to any
process on the system outside of a PAG running as the same UID.  AFS
tokens obtained inside a PAG are visible to any process in the same PAG,
regardless of UID.

=item setpag()

Creates a new, empty PAG and put the current process in it.  This should
normally be called before obtaining new AFS tokens to isolate those tokens
from other processes on the system.  Returns true on success and throws
an exception on failure.

=item unlog()

Deletes all AFS tokens in the current PAG, similar to the action of
B<kdestroy> on a Kerberos ticket cache.  Returns true on success and
throws an exception on failure.

=back

=head1 DIAGNOSTICS

=over 4

=item PAG creation failed: %s

setpag() failed.  The end of the error message will be a translation of
the system call error number.

=item Token deletion failed: %s

unlog() failed.  The end of the error message will be a translation of
the system call error number.

=back

=head1 RESTRICTIONS

This module currently doesn't provide the k_pioctl() or pioctl() function
to make lower-level AFS system calls.  It also doesn't provide the libkafs
functions to obtain AFS tokens from Kerberos tickets directly without using
an external ticket cache.  This prevents use of internal Kerberos ticket
caches (such as memory caches), since the Kerberos tickets used to generate
AFS tokens have to be visible to an external B<aklog> program.

=head1 AUTHOR

Russ Allbery <rra@cpan.org>

=head1 SEE ALSO

aklog(1)

The current version of this module is always available from its web site
at L<http://www.eyrie.org/~eagle/software/afs-pag/>.

=cut

lib/AFS/PAG.xs  view on Meta::CPAN

/* -*- c -*-
 * Perl bindings for the libkafs PAG functions.
 *
 * This is an XS source file, suitable for processing by xsubpp, that
 * generates Perl bindings for the PAG functions in the libkafs library or any
 * similar library that provides the same interface.  The module exports those
 * functions to Perl without the k_* prefix, since Perl already has good
 * namespace management for imports.
 *
 * Written by Russ Allbery <rra@cpan.org>
 * Copyright 2013
 *     The Board of Trustees of the Leland Stanford Junior University
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 */

#include <glue/config.h>
#include <portable/kafs.h>
#include <portable/system.h>

#include <EXTERN.h>
#include <perl.h>
#include <XSUB.h>

#include <errno.h>

/* XS code below this point. */

MODULE = AFS::PAG       PACKAGE = AFS::PAG

PROTOTYPES: DISABLE

void
hasafs()
  PPCODE:
    if (k_hasafs())
        XSRETURN_YES;
    else
        XSRETURN_UNDEF;


void
haspag()
  PPCODE:
    if (k_haspag())
        XSRETURN_YES;
    else
        XSRETURN_UNDEF;


void
setpag()
  PPCODE:
    if (k_setpag() == 0)
        XSRETURN_YES;
    else
        croak("PAG creation failed: %s", strerror(errno));


void
unlog()
  PPCODE:
    if (k_unlog() == 0)
        XSRETURN_YES;
    else
        croak("Token deletion failed: %s", strerror(errno));

portable/k_haspag.c  view on Meta::CPAN

/*
 * Replacement for missing k_haspag kafs function.
 *
 * k_haspag is a relatively new addition to the kafs interface (implemented by
 * Heimdal's libkafs and OpenAFS's libkopenafs).  It returns true if the
 * current process is in a PAG and false otherwise.  This is a replacement
 * function for libraries that don't have it or for use with a replacement
 * kafs layer.  It falls back on looking at the current process's supplemental
 * groups if the system call isn't supported or if k_pioctl isn't available.
 *
 * The canonical version of this file is maintained in the rra-c-util package,
 * which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>.
 *
 * Written by Russ Allbery <eagle@eyrie.org>
 *
 * The authors hereby relinquish any claim to any copyright that they may have
 * in this work, whether granted under contract or by operation of law or
 * international treaty, and hereby commit to the public, at large, that they
 * shall not, at any time in the future, seek to enforce any copyright in this
 * work against any person or entity, or prevent any person or entity from
 * copying, publishing, distributing or creating derivative works of this
 * work.
 */

#include <config.h>
#include <portable/kafs.h>
#include <portable/system.h>

#ifdef HAVE_SYS_IOCCOM_H
# include <sys/ioccom.h>
#endif
#include <sys/ioctl.h>


/*
 * The haspag function.  Returns true if the current process is in a PAG,
 * false otherwise.  This attempts a system call, and if that fails, falls
 * back on looking for supplemental groups that match the AFS groups.
 */
int
k_haspag(void)
{
    int ngroups, i;
    gid_t *groups;
    uint32_t pag, g0, g1, hi, lo;

    /* First, try the system call if k_pioctl is available. */
#ifdef HAVE_K_PIOCTL
    int result;
    struct ViceIoctl iob;

    iob.in = NULL;
    iob.in_size = 0;
    iob.out = (void *) &pag;
    iob.out_size = sizeof(pag);
    result = k_pioctl(NULL, _IOW('C', 13, struct ViceIoctl), &iob, 0);
    if (result == 0)
        return pag != (uint32_t) -1;
#endif

    /*
     * If that failed, the cache manager may not support the VIOC_GETPAG
     * system call.  Fall back on analyzing the groups.
     */
    ngroups = getgroups(0, NULL);
    groups = calloc(ngroups, sizeof(*groups));
    if (groups == NULL)
        return 0;
    ngroups = getgroups(ngroups, groups);

    /*
     * Strictly speaking, the single group PAG is only used on Linux, but
     * check it everywhere anyway to simplify life.
     */
    for (i = 0; i < ngroups; i++)
        if (((groups[i] >> 24) & 0xff) == 'A') {
            free(groups);
            return 1;
        }

    /*
     * Check for the PAG group pair.  The first two groups, when combined with
     * a rather strange formula, must result in a number matching the single
     * group number we already checked for.
     */
    if (ngroups < 2) {
        free(groups);
        return 0;
    }
    g0 = (groups[0] & 0xffff) - 0x3f00;
    g1 = (groups[1] & 0xffff) - 0x3f00;
    free(groups);
    if (g0 < 0xc0000 && g1 < 0xc0000) {
        lo = ((g0 & 0x3fff) << 14) | (g1 & 0x3fff);
        hi = (g1 >> 14) + (g0 >> 14) * 3;
        pag = ((hi << 28) | lo);
        return ((pag >> 24) & 0xff) == 'A';
    }
    return 0;
}

portable/kafs.h  view on Meta::CPAN

/*
 * Portability wrapper around the kafs API.
 *
 * This header includes kafs.h if it's available, prototypes k_hasafs,
 * k_setpag, and k_unlog replacements (generally provided by the kafs
 * replacement library) imlemented in terms of our system call layer or
 * lsetpag if it is available and libkafs isn't, and as a last resort provides
 * a k_hasafs function that always fails and k_setpag and k_unlog functions
 * that always succeed.
 *
 * It also defines the HAVE_KAFS macro to 1 if some AFS support was available,
 * in case programs that use it want to handle the case of no AFS support
 * differently (such as in help output).
 *
 * The canonical version of this file is maintained in the rra-c-util package,
 * which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>.
 *
 * Written by Russ Allbery <eagle@eyrie.org>
 * Copyright 2006, 2007, 2008, 2010, 2013
 *     The Board of Trustees of the Leland Stanford Junior University
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 */

#ifndef PORTABLE_KAFS_H
#define PORTABLE_KAFS_H 1

#include <config.h>
#ifdef HAVE_KRB5
# include <portable/krb5.h>
#endif
#include <portable/macros.h>

#include <errno.h>
#ifdef HAVE_SYS_IOCCOM_H
# include <sys/ioccom.h>
#endif
#include <sys/ioctl.h>

BEGIN_DECLS

/* Assume we have some AFS support available and #undef below if not. */
#define HAVE_KAFS 1

/* We have a libkafs or libkopenafs library. */
#if HAVE_K_HASAFS
# if HAVE_KAFS_H
#  include <kafs.h>
# elif HAVE_KOPENAFS_H
#  include <kopenafs.h>
# else
struct ViceIoctl {
    void *in, *out;
    short in_size;
    short out_size;
};
int k_hasafs(void);
int k_pioctl(char *, struct ViceIoctl *, void *, int);
int k_setpag(void);
int k_unlog(void);
# endif
# ifdef HAVE_K_HASPAG
#  if !defined(HAVE_KAFS_H) && !defined(HAVE_KOPENAFS_H)
int k_haspag(void);
#  endif
# else
int k_haspag(void) __attribute__((__visibility__("hidden")));
# endif

/* We're linking directly to the OpenAFS libraries. */
#elif HAVE_LSETPAG
# if HAVE_AFS_AFSSYSCALLS_H
#  include <afs/afssyscalls.h>
# else
int lsetpag(void);
int lpioctl(char *, int, void *, int);
# endif
# define k_hasafs()           (1)
# define k_pioctl(p, c, a, f) lpioctl((p), (c), (a), (f))
# define k_setpag()           lsetpag()
# define k_unlog()            (errno = ENOSYS, -1)

int k_haspag(void) __attribute__((__visibility__("hidden")));

/* We're using our local kafs replacement. */
#elif HAVE_KAFS_REPLACEMENT
# define HAVE_K_PIOCTL 1

struct ViceIoctl {
    void *in, *out;
    short in_size;
    short out_size;
};

/* Default to a hidden visibility for all portability functions. */
#pragma GCC visibility push(hidden)

int k_hasafs(void);
int k_haspag(void);
int k_pioctl(char *, int, struct ViceIoctl *, int);
int k_setpag(void);
int k_unlog(void);

/* Undo default visibility change. */
#pragma GCC visibility pop

/* We have no kafs implementation available. */
#else
# undef HAVE_KAFS
# define k_hasafs()           (0)
# define k_haspag()           (0)
# define k_pioctl(p, c, a, f) (errno = ENOSYS, -1)
# define k_setpag()           (errno = ENOSYS, -1)
# define k_unlog()            (errno = ENOSYS, -1)
#endif

END_DECLS

#endif /* PORTABLE_KAFS_H */

portable/macros.h  view on Meta::CPAN

/*
 * Portability macros used in include files.
 *
 * The canonical version of this file is maintained in the rra-c-util package,
 * which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>.
 *
 * Written by Russ Allbery <eagle@eyrie.org>
 *
 * The authors hereby relinquish any claim to any copyright that they may have
 * in this work, whether granted under contract or by operation of law or
 * international treaty, and hereby commit to the public, at large, that they
 * shall not, at any time in the future, seek to enforce any copyright in this
 * work against any person or entity, or prevent any person or entity from
 * copying, publishing, distributing or creating derivative works of this
 * work.
 */

#ifndef PORTABLE_MACROS_H
#define PORTABLE_MACROS_H 1

/*
 * __attribute__ is available in gcc 2.5 and later, but only with gcc 2.7
 * could you use the __format__ form of the attributes, which is what we use
 * (to avoid confusion with other macros).
 */
#ifndef __attribute__
# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7)
#  define __attribute__(spec)   /* empty */
# endif
#endif

/*
 * We use __alloc_size__, but it was only available in fairly recent versions
 * of GCC.  Suppress warnings about the unknown attribute if GCC is too old.
 * We know that we're GCC at this point, so we can use the GCC variadic macro
 * extension, which will still work with versions of GCC too old to have C99
 * variadic macro support.
 */
#if !defined(__attribute__) && !defined(__alloc_size__)
# if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 3)
#  define __alloc_size__(spec, args...) /* empty */
# endif
#endif

/*
 * LLVM and Clang pretend to be GCC but don't support all of the __attribute__
 * settings that GCC does.  For them, suppress warnings about unknown
 * attributes on declarations.  This unfortunately will affect the entire
 * compilation context, but there's no push and pop available.
 */
#if !defined(__attribute__) && (defined(__llvm__) || defined(__clang__))
# pragma GCC diagnostic ignored "-Wattributes"
#endif

/*
 * BEGIN_DECLS is used at the beginning of declarations so that C++
 * compilers don't mangle their names.  END_DECLS is used at the end.
 */
#undef BEGIN_DECLS
#undef END_DECLS
#ifdef __cplusplus
# define BEGIN_DECLS    extern "C" {
# define END_DECLS      }
#else
# define BEGIN_DECLS    /* empty */
# define END_DECLS      /* empty */
#endif

#endif /* !PORTABLE_MACROS_H */

portable/stdbool.h  view on Meta::CPAN

/*
 * Portability wrapper around <stdbool.h>.
 *
 * Provides the bool and _Bool types and the true and false constants,
 * following the C99 specification, on hosts that don't have stdbool.h.  This
 * logic is based heavily on the example in the Autoconf manual.
 *
 * The canonical version of this file is maintained in the rra-c-util package,
 * which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>.
 *
 * Written by Russ Allbery <eagle@eyrie.org>
 *
 * The authors hereby relinquish any claim to any copyright that they may have
 * in this work, whether granted under contract or by operation of law or
 * international treaty, and hereby commit to the public, at large, that they
 * shall not, at any time in the future, seek to enforce any copyright in this
 * work against any person or entity, or prevent any person or entity from
 * copying, publishing, distributing or creating derivative works of this
 * work.
 */

#ifndef PORTABLE_STDBOOL_H
#define PORTABLE_STDBOOL_H 1

/*
 * Allow inclusion of config.h to be skipped, since sometimes we have to use a
 * stripped-down version of config.h with a different name.
 */
#ifndef CONFIG_H_INCLUDED
# include <config.h>
#endif

#if HAVE_STDBOOL_H
# include <stdbool.h>
#else
# if HAVE__BOOL
#  define bool _Bool
# else
#  ifdef __cplusplus
typedef bool _Bool;
#  elif _WIN32
#   include <windef.h>
#   define bool BOOL
#  else
typedef unsigned char _Bool;
#   define bool _Bool
#  endif
# endif
# define false 0
# define true  1
# define __bool_true_false_are_defined 1
#endif

/*
 * If we define bool and don't tell Perl, it will try to define its own and
 * fail.  Only of interest for programs that also include Perl headers.
 */
#ifndef HAS_BOOL
# define HAS_BOOL 1
#endif

#endif /* !PORTABLE_STDBOOL_H */

portable/system.h  view on Meta::CPAN

/*
 * Standard system includes and portability adjustments.
 *
 * Declarations of routines and variables in the C library.  Including this
 * file is the equivalent of including all of the following headers,
 * portably:
 *
 *     #include <inttypes.h>
 *     #include <limits.h>
 *     #include <stdarg.h>
 *     #include <stdbool.h>
 *     #include <stddef.h>
 *     #include <stdio.h>
 *     #include <stdlib.h>
 *     #include <stdint.h>
 *     #include <string.h>
 *     #include <strings.h>
 *     #include <sys/types.h>
 *     #include <unistd.h>
 *
 * Missing functions are provided via #define or prototyped if available from
 * the portable helper library.  Also provides some standard #defines.
 *
 * The canonical version of this file is maintained in the rra-c-util package,
 * which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>.
 *
 * Written by Russ Allbery <eagle@eyrie.org>
 *
 * The authors hereby relinquish any claim to any copyright that they may have
 * in this work, whether granted under contract or by operation of law or
 * international treaty, and hereby commit to the public, at large, that they
 * shall not, at any time in the future, seek to enforce any copyright in this
 * work against any person or entity, or prevent any person or entity from
 * copying, publishing, distributing or creating derivative works of this
 * work.
 */

#ifndef PORTABLE_SYSTEM_H
#define PORTABLE_SYSTEM_H 1

/* Make sure we have our configuration information. */
#include <config.h>

/* BEGIN_DECL and __attribute__. */
#include <portable/macros.h>

/* A set of standard ANSI C headers.  We don't care about pre-ANSI systems. */
#if HAVE_INTTYPES_H
# include <inttypes.h>
#endif
#include <limits.h>
#include <stdarg.h>
#include <stddef.h>
#if HAVE_STDINT_H
# include <stdint.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#if HAVE_STRINGS_H
# include <strings.h>
#endif
#include <sys/types.h>
#if HAVE_UNISTD_H
# include <unistd.h>
#endif

/* SCO OpenServer gets int32_t from here. */
#if HAVE_SYS_BITYPES_H
# include <sys/bitypes.h>
#endif

/* Get the bool type. */
#include <portable/stdbool.h>

/* Windows provides snprintf under a different name. */
#ifdef _WIN32
# define snprintf _snprintf
#endif

/* Define sig_atomic_t if it's not available in signal.h. */
#ifndef HAVE_SIG_ATOMIC_T
typedef int sig_atomic_t;
#endif

/* Windows does not define ssize_t. */
#ifndef HAVE_SSIZE_T
typedef ptrdiff_t ssize_t;
#endif

/*
 * POSIX requires that these be defined in <unistd.h>.  If one of them has
 * been defined, all the rest almost certainly have.
 */
#ifndef STDIN_FILENO
# define STDIN_FILENO  0
# define STDOUT_FILENO 1
# define STDERR_FILENO 2
#endif

/*
 * C99 requires va_copy.  Older versions of GCC provide __va_copy.  Per the
 * Autoconf manual, memcpy is a generally portable fallback.
 */
#ifndef va_copy
# ifdef __va_copy
#  define va_copy(d, s) __va_copy((d), (s))
# else
#  define va_copy(d, s) memcpy(&(d), &(s), sizeof(va_list))
# endif
#endif

#endif /* !PORTABLE_SYSTEM_H */

t/data/perl.conf  view on Meta::CPAN

# Configuration for Perl tests.  -*- perl -*-

# Default minimum version requirement.
$MINIMUM_VERSION = '5.010';

# File must end with this line.
1;

t/data/perlcriticrc  view on Meta::CPAN

# -*- conf -*-
#
# Default configuration for perlcritic.  Be sure to copy this into the source
# for packages that run perlcritic tests automatically during the build for
# reproducible test results.
#
# This file has been updated to match perlcritic 1.118.
#
# The canonical version of this file is maintained in the rra-c-util package,
# which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>.
#
# Written by Russ Allbery <eagle@eyrie.org>
# Copyright 2011, 2012, 2013
#     The Board of Trustees of the Leland Stanford Junior University
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
# DEALINGS IN THE SOFTWARE.

severity = 1
verbose  = %f:%l:%c: [%p] %m (%e, Severity: %s)\n

# I prefer this policy (a lot, actually), but other people in my group at
# Stanford really didn't like it, so this is my compromise to agree with a
# group coding style.
[-CodeLayout::ProhibitParensWithBuiltins]

# Stanford's coding style allows postfix unless for flow control.  There
# doesn't appear to be any way to allow it only for flow control (the logic
# for "if" and "when" appears to be special-cased), so we have to allow unless
# globally.
[ControlStructures::ProhibitPostfixControls]
allow = unless

# This is handled with a separate test case that uses Test::Spelling.
[-Documentation::PodSpelling]

# Pod::Man and Pod::Text fixed this bug years ago.  I know, I maintain them.
[-Documentation::RequirePodLinksIncludeText]

# The POD sections Perl::Critic wants are incompatible with the POD template
# from perlpodstyle, which is what I use for my POD documentation.
[-Documentation::RequirePodSections]

# This problem was fixed in Perl 5.14, which now properly preserves the value
# of $@ even if destructors run at exit from the eval block.
[-ErrorHandling::RequireCheckingReturnValueOfEval]

# The default of 9 is too small and forces weird code contortions.
[InputOutput::RequireBriefOpen]
lines = 25

# This is correct 80% of the time, but it isn't correct for a lot of scripts
# inside packages, where maintaining $VERSION isn't worth the effort.
# Unfortunately, there's no way to override it, so it gets turned off
# globally.
[-Modules::RequireVersionVar]

# This sounds interesting but is actually useless.  Any large blocks of
# literal text, which does not add to the complexity of the regex, will set it
# off.
[-RegularExpressions::ProhibitComplexRegexes]

# I generally don't want to require Readonly as a prerequisite for all my Perl
# modules.
[-ValuesAndExpressions::ProhibitConstantPragma]

# A good idea, but there are too many places where this would be more
# confusing than helpful.  Pull out numbers if one might change them
# independent of the algorithm, but don't do so for mathematical formulae.
[-ValuesAndExpressions::ProhibitMagicNumbers]

# Increase this to six digits so that I'm not told to add underscores to
# port numbers (which is just silly).
[ValuesAndExpressions::RequireNumberSeparators]
min_value = 100000

# Text::Wrap has a broken interface that requires use of package variables.
[Variables::ProhibitPackageVars]
add_packages = Text::Wrap

# use English was one of the worst ideas in the history of Perl.  It makes the
# code slightly more readable for amateurs at the cost of confusing
# experienced Perl programmers and sending people in futile quests for where
# these magical global variables are defined.
[-Variables::ProhibitPunctuationVars]

t/data/perltidyrc  view on Meta::CPAN

# -*- conf -*-
#
# Default options for perltidy for proper Perl code reformatting.
#
# The canonical version of this file is maintained in the rra-c-util package,
# which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>.

-bbao           # put line breaks before any operator
-nbbc           # don't force blank lines before comments (bad for else blocks)
-ce             # cuddle braces around else
-l=79           # usually use 78, but don't want 79-long lines reformatted
-pt=2           # don't add extra whitespace around parentheses
-sbt=2          # ...or square brackets
-sfs            # no space before semicolon in for (not that I use this form)

t/docs/pod-coverage.t  view on Meta::CPAN

#!/usr/bin/perl
#
# Test that all methods are documented in POD.
#
# The canonical version of this file is maintained in the rra-c-util package,
# which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>.
#
# Written by Russ Allbery <eagle@eyrie.org>
# Copyright 2013, 2014
#     The Board of Trustees of the Leland Stanford Junior University
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
# DEALINGS IN THE SOFTWARE.

use 5.006;
use strict;
use warnings;

use lib 't/lib';

use Test::More;
use Test::RRA qw(skip_unless_automated use_prereq);
use Test::RRA::Config qw(@POD_COVERAGE_EXCLUDE);

# Skip for normal user installs since this doesn't affect functionality.
skip_unless_automated('POD coverage tests');

# Load prerequisite modules.
use_prereq('Test::Pod::Coverage');

# Test everything found in the distribution.
all_pod_coverage_ok({ also_private => [@POD_COVERAGE_EXCLUDE] });

t/docs/pod-spelling.t  view on Meta::CPAN

#!/usr/bin/perl
#
# Check for spelling errors in POD documentation.
#
# The canonical version of this file is maintained in the rra-c-util package,
# which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>.
#
# Written by Russ Allbery <eagle@eyrie.org>
# Copyright 2013, 2014
#     The Board of Trustees of the Leland Stanford Junior University
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
# DEALINGS IN THE SOFTWARE.

use 5.006;
use strict;
use warnings;

use lib 't/lib';

use Test::More;
use Test::RRA qw(skip_unless_author use_prereq);

# Only run this test for the module author since the required stopwords are
# too sensitive to the exact spell-checking program and dictionary.
skip_unless_author('Spelling tests');

# Load prerequisite modules.
use_prereq('Test::Spelling');

# Check all POD in the Perl distribution.  Add the examples directory if it
# exists.  Also add any files in usr/bin or usr/sbin, which are widely used in
# Stanford-internal packages.
my @files = all_pod_files();
if (-d 'examples') {
    push(@files, all_pod_files('examples'));
}
for my $dir (qw(usr/bin usr/sbin)) {
    if (-d $dir) {
        push(@files, glob("$dir/*"));
    }
}

# We now have a list of all files to check, so output a plan and run the
# tests.  We can't use all_pod_files_spelling_ok because it refuses to check
# non-Perl files and Stanford-internal packages have a lot of shell scripts
# with POD documentation.
plan tests => scalar(@files);
for my $file (@files) {
    pod_file_spelling_ok($file);
}

t/docs/pod.t  view on Meta::CPAN

#!/usr/bin/perl
#
# Check all POD documents for POD formatting errors.
#
# The canonical version of this file is maintained in the rra-c-util package,
# which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>.
#
# Written by Russ Allbery <eagle@eyrie.org>
# Copyright 2012, 2013, 2014
#     The Board of Trustees of the Leland Stanford Junior University
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
# DEALINGS IN THE SOFTWARE.

use 5.006;
use strict;
use warnings;

use lib 't/lib';

use Test::More;
use Test::RRA qw(skip_unless_automated use_prereq);

# Skip this test for normal user installs, although pod2man may still fail.
skip_unless_automated('POD syntax tests');

# Load prerequisite modules.
use_prereq('Test::Pod');

# Check all POD in the Perl distribution.  Add the examples directory if it
# exists.  Also add any files in usr/bin or usr/sbin, which are widely used in
# Stanford-internal packages.
my @files = all_pod_files();
if (-d 'examples') {
    push(@files, all_pod_files('examples'));
}
for my $dir (qw(usr/bin usr/sbin)) {
    if (-d $dir) {
        push(@files, glob("$dir/*"));
    }
}

# We now have a list of all files to check, so output a plan and run the
# tests.  We can't use all_pod_files_ok because it refuses to check non-Perl
# files and Stanford-internal packages have a lot of shell scripts with POD
# documentation.
plan tests => scalar(@files);
for my $file (@files) {
    pod_file_ok($file);
}

t/docs/synopsis.t  view on Meta::CPAN

#!/usr/bin/perl
#
# Check the SYNOPSIS section of the documentation for syntax errors.
#
# The canonical version of this file is maintained in the rra-c-util package,
# which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>.
#
# Written by Russ Allbery <eagle@eyrie.org>
# Copyright 2013, 2014
#     The Board of Trustees of the Leland Stanford Junior University
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
# DEALINGS IN THE SOFTWARE.

use 5.006;
use strict;
use warnings;

use lib 't/lib';

use Test::More;
use Test::RRA qw(skip_unless_automated use_prereq);

# Skip for normal user installs since this doesn't affect functionality.
skip_unless_automated('Synopsis syntax tests');

# Load prerequisite modules.
use_prereq('Perl::Critic::Utils');
use_prereq('Test::Synopsis');

# The default Test::Synopsis all_synopsis_ok() function requires that the
# module be in a lib directory.  Use Perl::Critic::Utils to find the modules
# in blib, or lib if it doesn't exist.  However, strip out anything in
# blib/script, since scripts use a different SYNOPSIS syntax.
my @files = Perl::Critic::Utils::all_perl_files('blib');
@files = grep { !m{blib/script/}xms } @files;
if (!@files) {
    @files = Perl::Critic::Utils::all_perl_files('lib');
}
plan tests => scalar @files;

# Run the actual tests.
for my $file (@files) {
    synopsis_ok($file);
}



( run in 0.496 second using v1.01-cache-2.11-cpan-a5abf4f5562 )