X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=perl%2FAmanda%2FUtil.pod;fp=perl%2FAmanda%2FUtil.pod;h=b33627ce7bdee00cdf66554fa59eba697c95c49a;hb=fd48f3e498442f0cbff5f3606c7c403d0566150e;hp=0000000000000000000000000000000000000000;hpb=96f35b20267e8b1a1c846d476f27fcd330e0b018;p=debian%2Famanda diff --git a/perl/Amanda/Util.pod b/perl/Amanda/Util.pod new file mode 100644 index 0000000..b33627c --- /dev/null +++ b/perl/Amanda/Util.pod @@ -0,0 +1,399 @@ +/* + * Copyright (c) 2009, 2010 Zmanda, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Contact information: Zmanda Inc., 465 S. Mathilda Ave., Suite 300 + * Sunnyvale, CA 94085, USA, or: http://www.zmanda.com + */ + +%perlcode %{ + +=head1 NAME + +Amanda::Util - Runtime support for Amanda applications + +=head1 Application Initialization + +Application initialization generally looks like this: + + use Amanda::Config qw( :init ); + use Amanda::Util qw( :constants ); + use Amanda::Debug; + + Amanda::Util::setup_application("myapp", "server", $CONTEXT_CMDLINE); + # .. command-line processing .. + Amanda::Config::config_init(...); + Amanda::Util::finish_setup($RUNNING_AS_DUMPUSER); + # .. + Amanda::Util::finish_application(); + +=over + +=item setup_application($name, $type, $context) + +Set up the operating environment for an application, without requiring +any configuration. + +C<$name> is the name of the application, used in log messages, etc. +C<$type> is usualy one of "server" or "client". It specifies the +subdirectory in which debug logfiles will be created. C<$context> +indicates the usual manner in which this application is invoked; one +of C<$CONTEXT_CMDLINE> for a user-invoked command-line utility (e.g., +C) which should send human-readable error messages to stderr; +C<$CONTEXT_DAEMON> for a program started by C, e.g., +C; or C<$CONTEXT_SCRIPTUTIL> for a small program used from +shell scripts, e.g., C + +Based on C<$type> and C<$context>, this function does the following: + +=over + +=item * + +sets up debug logging; + +=item * + +configures internationalization + +=item * + +sets the umask; + +=item * + +sets the current working directory to the debug or temporary +directory; + +=item * + +closes any unnecessary file descriptors as a security meaasure; + +=item * + +ignores C; and + +=item * + +sets the appropriate target for error messages. + +=back + +=item finish_setup($running_as_flags) + +Perform final initialization tasks that require a loaded +configuration. Specifically, move the debug log into a +configuration-specific subdirectory, and check that the current userid +is appropriate for this applciation. + +The user is specified by one of the following flags, which are +available in export tag C<:check_running_as_flags>: + + $RUNNING_AS_ANY # any user is OK + $RUNNING_AS_ROOT # root + $RUNNING_AS_DUMPUSER # dumpuser, from configuration + $RUNNING_AS_DUMPUSER_PREFERRED # dumpuser, but client_login is OK too + $RUNNING_AS_CLIENT_LOGIN # client_login (--with-user at build time) + +If the flag C<$RUNNING_AS_UID_ONLY> is bit-or'd into +C<$running_as_flags>, then the euid is ignored; this is used for +programs that expect to be setuid-root. + +=item finish_application() + +Remove old debug files. +All applications should call this before exiting. + +=item get_original_cwd() + +Return the original current directory with C. + +=item version_opt() + +Print the version and exit. This is intended to be used in C invocations, e.g., + + GetOptions( + # ... + 'version' => \&Amanda::Util::version_opt, + ); + +=back + +=head1 File Handling + +These functions read and write the entire requested size to a file +descriptor, even if the underlying syscall returns early. Note that +they do not operate on Perl file handles. + +If fewer than C<$size> bytes are written, C returns the +number of bytes actually written and sets C<$!> appropriately. When +reading, if fewer than C<$size> bytes are read due to a normal EOF, +then C<$!> is zero; otherwise, it contains the appropriate error +message. + +Unlike C, C returns a scalar containing the +bytes it read from the file descriptor. + +=over + +=item full_read($fd, $size) + +=item full_write($fd, $buf, $size) + +=back + +=head1 Miscellaneous Utilities + +=over + +=item safe_env() + +Return a "safe" environment hash. For non-setuid programs, this means +filtering out any localization variables. + +=item get_fs_usage(file, disk) + +This is a wrapper around the Gnulib function of the same name. On success, it returns +a hash with keys: + + blocksize Size of a block + blocks Total blocks on disk + bfree Free blocks available to superuser + bavail Free blocks available to non-superuser + bavail_top_bit_set 1 if fsu_bavail represents a value < 0 + files Total file nodes + ffree Free file nodes + +On failure, it returns nothing, and C<$!> should be set. If C<$!> is 0, then +this is a system which cannot measure usage without a C argument, which +this wrapper does not support. + +=item is_pid_alive(pid) + +Return 1 is the process with that pid is still alive. + +=item weaken_ref($ref) + +This is exactly the same as C, but available in all +supported versions of perl. + +=item gettimeofday() + +Return the number of microseconds since the UNIX epoch. + +=item fsync($fd) + +Invoke the C syscall. + +=item set_blocking($fd, $blocking) + +Set or clear the C fd flag on $fd; returns a negative value on +failure, or 0 on success. + +=item openbsd_fd_inform() + +Due to a particularly poor user-space implementation of threading on OpenBSD, +executables that are run with nonstandard file descriptors open (fd > 2) find +those descriptors to be in a nonblocking state. This particularly affects +amandad services, which begin with several file descriptors in the 50's open. + +This function "informs" the C library about these descriptors by making an +C call. This is otherwise harmless, and is only perfomed +on OpenBSD. + +=item built_with_component($comp) + +Returns true if Amanda was built with the given component. Component names are +in C. + +=back + +=head1 TCP Utilities + +These are thin wrappers over functions in C and other related +functions. + +=over + +=item stream_server + + my $family = $Amanda::Util::AF_INET; + my $bufsize = $Amanda::Util::STREAM_BUFSIZE; + my ($listensock, $port) = Amanda::Util::stream_server( + $family, $bufsize, $bufsize, $priv); + +This function creates a new socket and binds it to a port, returning both the +socket and port. If the socket is -1, then an error occurred and is available +in C<$!>. The constants C<$AF_INET> and C<$STREAM_BUFSIZE> are universally +used when calling this function. If the final argument, C<$priv>, is true, +then a the function opens a privileged port (below 1024). + +=item stream_accept + + my $sock = Amanda::Util::stream_accept( + $listen_sock, $timeout, $bufsize, $bufsize); + +This function accepts a connection on a listening socket. If the connection is +not made within C<$timeout> seconds, or some other error occurs, then the +function returns -1. The bufsize arguments are applied to the new socket. + +=item check_security + + my $ok = Amanda::Util::check_security($socket, $userstr); + +This function takes a socket descriptor and a string of the form C<"USER foo"> +and performs BSD-style checks on that descriptor. These include verifying +round-trip DNS sanity; check that the user is in C<.rhosts> or C<.amandahosts>, +and checking that the remote port is reserved. Returns an error string on +error, or C on success. + +=back + +=head1 String Utilities + +=over + +=item quote_string($str) + +Quote a string using Amanda's quoting algorithm. Strings with no +whitespace, control, or quote characters are returned unchanged. An +empty string is represented as the two-character string C<"">. +Otherwise, tab, newline, carriage return, form-feed, backslash, and +double-quote (C<">) characters are escaped with a backslash and the +string is surrounded by double quotes. + +=item unquote_string($str) + +Unquote a string as quoted with C. + +=item skip_quoted_string($str) + +my($q, $remaider) = skip_quoted_string($str) + +Return the first quoted string and the remainder of the string. + +=item C + +Split string on unquoted whitespace. Multiple consecutive spaces are not +collapsed into a single space: C<"x y"> (with two spaces) parses as C<( "x", +"", "y")>. The strings are unquoted before they are returned. An empty string +is split into C<( "" )>. + +All of these quoting-related functions are available under the export +tag C<:quoting>. + +=item hexencode($str) + +Encode a string using URI-style hexadecimal encoding. +Non-alphanumeric characters will be replaced with "%xx" +where "xx" is the two-digit hexadecimal representation of the character. + +=item hexdecode($str) + +Decode a string using URI-style hexadecimal encoding. + +Both C and C are available under the export tag C<:encoding> + +=item expand_braced_alternates($str) +=item collapse_braced_alternates(\@list) + +These two functions handle "braced alternates", which is a syntax +borrowed, partially, from shells. Comma-separated strings enclosed in +curly braces expand into multiple alternatives for the entire string. +For example: + + "{foo,bar,bat}" [ "foo", "bar", "bat" ] + "foo{1,2}bar" [ "foo1bar", "foo2bar" ] + "foo{1\,2,3}bar" [ "foo1,2bar", "foo3bar" ] + "{a,b}-{1,2}" [ "a-1", "a-2", "b-1", "b-2" ] + +Note that nested braces are not processed. Braces, commas, and +backslashes may be escaped with backslashes. On error, +C returns undef. These two functions are +available in the export tag C<:alternates>. + +=item generate_timestamp() + +Generate a timestamp from the current time, obeying the +'USETIMESTAMPS' config parameter. The Amanda configuration must +already be loaded. + +=item sanitise_filename($fn) + +"Santitises" a filename by replacing any characters that might have special +meaning to a filesystem with underscores. This operation is I reversible, +and distinct input filenames I produce identical output filenames. + +=item unmarshal_tapespec($tapespec) +=item marshal_tapespec($filelist) + +These functions convert between a tapespec -- formerly, and confusingly, called +a "tapelist" -- and a perl data structure like + + [ $label1 => [ $filenum1, $filenum2, .. ], + $label2 => [ $filenum1, $filenum2, .. ], + ] + +Note that a non-tapespec C<$string> will be unmarshalled as C<[ $string, [] ]>. + +=back + +=head1 Locking Files + +Amanda provides a basic mechanism to lock a file and read its contents. This +uses operating-system facilities to acquire an advisory lock, so non-Amanda +applications are not prevented from modifying the file while it is locked. + +To create a lock object, call the C constructor, passing the +filename to lock: + + my $fl = Amanda::Util::file_lock->new($filename) + +then, lock the file: + + $fl->lock(); + +which also reads the contents of the file into memory, accessible via + + my $state = $fl->data(); + +to change the file contents, call C: + + $fl->write($new_contents); + +and unlock the lock with + + $fl->unlock(); + +Note that the file will be automatically unlocked if the C object is +garbage-collected. + +=head1 Simple File Reading & Writing + +For reading small files directly into memory with little code +overhead, we can use C. + + my $data = slurp $filename; + +After processing the data, we can write it back to file with C. This +function always completely overwrites the file. + + burp $filename, $header; + +These functions can (and should) be exported to the main namespace + +=cut + +%}