2 * Copyright (c) 2009, 2010 Zmanda, Inc. All Rights Reserved.
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 2 as published
6 * by the Free Software Foundation.
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
10 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write to the Free Software Foundation, Inc.,
15 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 * Contact information: Zmanda Inc., 465 S. Mathilda Ave., Suite 300
18 * Sunnyvale, CA 94085, USA, or: http://www.zmanda.com
25 Amanda::Util - Runtime support for Amanda applications
27 =head1 Application Initialization
29 Application initialization generally looks like this:
31 use Amanda::Config qw( :init );
32 use Amanda::Util qw( :constants );
35 Amanda::Util::setup_application("myapp", "server", $CONTEXT_CMDLINE);
36 # .. command-line processing ..
37 Amanda::Config::config_init(...);
38 Amanda::Util::finish_setup($RUNNING_AS_DUMPUSER);
40 Amanda::Util::finish_application();
44 =item setup_application($name, $type, $context)
46 Set up the operating environment for an application, without requiring
49 C<$name> is the name of the application, used in log messages, etc.
50 C<$type> is usualy one of "server" or "client". It specifies the
51 subdirectory in which debug logfiles will be created. C<$context>
52 indicates the usual manner in which this application is invoked; one
53 of C<$CONTEXT_CMDLINE> for a user-invoked command-line utility (e.g.,
54 C<amadmin>) which should send human-readable error messages to stderr;
55 C<$CONTEXT_DAEMON> for a program started by C<amandad>, e.g.,
56 C<sendbackup>; or C<$CONTEXT_SCRIPTUTIL> for a small program used from
57 shell scripts, e.g., C<amgetconf>
59 Based on C<$type> and C<$context>, this function does the following:
65 sets up debug logging;
69 configures internationalization
77 sets the current working directory to the debug or temporary
82 closes any unnecessary file descriptors as a security meaasure;
86 ignores C<SIGPIPE>; and
90 sets the appropriate target for error messages.
94 =item finish_setup($running_as_flags)
96 Perform final initialization tasks that require a loaded
97 configuration. Specifically, move the debug log into a
98 configuration-specific subdirectory, and check that the current userid
99 is appropriate for this applciation.
101 The user is specified by one of the following flags, which are
102 available in export tag C<:check_running_as_flags>:
104 $RUNNING_AS_ANY # any user is OK
105 $RUNNING_AS_ROOT # root
106 $RUNNING_AS_DUMPUSER # dumpuser, from configuration
107 $RUNNING_AS_DUMPUSER_PREFERRED # dumpuser, but client_login is OK too
108 $RUNNING_AS_CLIENT_LOGIN # client_login (--with-user at build time)
110 If the flag C<$RUNNING_AS_UID_ONLY> is bit-or'd into
111 C<$running_as_flags>, then the euid is ignored; this is used for
112 programs that expect to be setuid-root.
114 =item finish_application()
116 Remove old debug files.
117 All applications should call this before exiting.
119 =item get_original_cwd()
121 Return the original current directory with C<get_original_cwd>.
125 Print the version and exit. This is intended to be used in C<GetOptions> invocations, e.g.,
129 'version' => \&Amanda::Util::version_opt,
136 These functions read and write the entire requested size to a file
137 descriptor, even if the underlying syscall returns early. Note that
138 they do not operate on Perl file handles.
140 If fewer than C<$size> bytes are written, C<full_write> returns the
141 number of bytes actually written and sets C<$!> appropriately. When
142 reading, if fewer than C<$size> bytes are read due to a normal EOF,
143 then C<$!> is zero; otherwise, it contains the appropriate error
146 Unlike C<POSIX::read>, C<full_read> returns a scalar containing the
147 bytes it read from the file descriptor.
151 =item full_read($fd, $size)
153 =item full_write($fd, $buf, $size)
157 =head1 Miscellaneous Utilities
163 Return a "safe" environment hash. For non-setuid programs, this means
164 filtering out any localization variables.
166 =item get_fs_usage(file, disk)
168 This is a wrapper around the Gnulib function of the same name. On success, it returns
171 blocksize Size of a block
172 blocks Total blocks on disk
173 bfree Free blocks available to superuser
174 bavail Free blocks available to non-superuser
175 bavail_top_bit_set 1 if fsu_bavail represents a value < 0
176 files Total file nodes
177 ffree Free file nodes
179 On failure, it returns nothing, and C<$!> should be set. If C<$!> is 0, then
180 this is a system which cannot measure usage without a C<disk> argument, which
181 this wrapper does not support.
183 =item is_pid_alive(pid)
185 Return 1 is the process with that pid is still alive.
187 =item weaken_ref($ref)
189 This is exactly the same as C<Scalar::Util::weaken>, but available in all
190 supported versions of perl.
194 Return the number of microseconds since the UNIX epoch.
198 Invoke the C<fsync> syscall.
200 =item set_blocking($fd, $blocking)
202 Set or clear the C<O_NONBLOCK> fd flag on $fd; returns a negative value on
203 failure, or 0 on success.
205 =item openbsd_fd_inform()
207 Due to a particularly poor user-space implementation of threading on OpenBSD,
208 executables that are run with nonstandard file descriptors open (fd > 2) find
209 those descriptors to be in a nonblocking state. This particularly affects
210 amandad services, which begin with several file descriptors in the 50's open.
212 This function "informs" the C library about these descriptors by making an
213 C<fcntl(fd, F_GETFL)> call. This is otherwise harmless, and is only perfomed
216 =item built_with_component($comp)
218 Returns true if Amanda was built with the given component. Component names are
219 in C<config/amanda/components.m4>.
225 These are thin wrappers over functions in C<common-src/stream.h> and other related
232 my $family = $Amanda::Util::AF_INET;
233 my $bufsize = $Amanda::Util::STREAM_BUFSIZE;
234 my ($listensock, $port) = Amanda::Util::stream_server(
235 $family, $bufsize, $bufsize, $priv);
237 This function creates a new socket and binds it to a port, returning both the
238 socket and port. If the socket is -1, then an error occurred and is available
239 in C<$!>. The constants C<$AF_INET> and C<$STREAM_BUFSIZE> are universally
240 used when calling this function. If the final argument, C<$priv>, is true,
241 then a the function opens a privileged port (below 1024).
245 my $sock = Amanda::Util::stream_accept(
246 $listen_sock, $timeout, $bufsize, $bufsize);
248 This function accepts a connection on a listening socket. If the connection is
249 not made within C<$timeout> seconds, or some other error occurs, then the
250 function returns -1. The bufsize arguments are applied to the new socket.
254 my $ok = Amanda::Util::check_security($socket, $userstr);
256 This function takes a socket descriptor and a string of the form C<"USER foo">
257 and performs BSD-style checks on that descriptor. These include verifying
258 round-trip DNS sanity; check that the user is in C<.rhosts> or C<.amandahosts>,
259 and checking that the remote port is reserved. Returns an error string on
260 error, or C<undef> on success.
264 =head1 String Utilities
268 =item quote_string($str)
270 Quote a string using Amanda's quoting algorithm. Strings with no
271 whitespace, control, or quote characters are returned unchanged. An
272 empty string is represented as the two-character string C<"">.
273 Otherwise, tab, newline, carriage return, form-feed, backslash, and
274 double-quote (C<">) characters are escaped with a backslash and the
275 string is surrounded by double quotes.
277 =item unquote_string($str)
279 Unquote a string as quoted with C<quote_string>.
281 =item skip_quoted_string($str)
283 my($q, $remaider) = skip_quoted_string($str)
285 Return the first quoted string and the remainder of the string, as separated by
286 any whitespace. Note that the remainder of the string does not include the
287 single separating whitespace character, but will include any subsequent
288 whitespace. The C<$q> is not unquoted.
290 =item C<split_quoted_strings($str)>
292 Split string on unquoted whitespace. Multiple consecutive spaces are I<not>
293 collapsed into a single space: C<"x y"> (with two spaces) parses as C<( "x",
294 "", "y")>. The strings are unquoted before they are returned. An empty string
295 is split into C<( "" )>. This method is generally used for parsing IPC messages,
296 where blank space is significant and well-controlled.
298 =item C<split_quoted_strings_friendly($str)>
300 Similar to C<split_quoted_strings>, but intended for user-friendly uses. In
301 particular, this function treats any sequence of zero or more whitespace
302 characters as a separator, rather than the more strict interpretation applied
303 by C<split_quoted_strings>. All of the strings are unquoted.
305 All of these quoting-related functions are available under the export
308 =item hexencode($str)
310 Encode a string using URI-style hexadecimal encoding.
311 Non-alphanumeric characters will be replaced with "%xx"
312 where "xx" is the two-digit hexadecimal representation of the character.
314 =item hexdecode($str)
316 Decode a string using URI-style hexadecimal encoding.
318 Both C<hexencode> and C<hexdecode> are available under the export tag C<:encoding>
320 =item expand_braced_alternates($str)
321 =item collapse_braced_alternates(\@list)
323 These two functions handle "braced alternates", which is a syntax
324 borrowed, partially, from shells. Comma-separated strings enclosed in
325 curly braces expand into multiple alternatives for the entire string.
328 "{foo,bar,bat}" [ "foo", "bar", "bat" ]
329 "foo{1,2}bar" [ "foo1bar", "foo2bar" ]
330 "foo{1\,2,3}bar" [ "foo1,2bar", "foo3bar" ]
331 "{a,b}-{1,2}" [ "a-1", "a-2", "b-1", "b-2" ]
333 Note that nested braces are not processed. Braces, commas, and
334 backslashes may be escaped with backslashes.
336 As a special case for numeric ranges, if the braces contain only digits
337 followed by two dots followed by more digits, and the digits sort in the
338 correct order, then they will be treated as a sequence. If the first number in
339 the sequence has leading zeroes, then all generated numbers will have that
340 length, padded with leading zeroes.
342 "tape-{01..10}" [ "tape-01", "tape-02", "tape-03", "tape-04",
343 "tape-05", "tape-06", "tape-07", "tape-08",
344 "tape-09", "tape-10" ]
346 On error, C<expand_braced_altnerates> returns undef. These two functions are
347 available in the export tag C<:alternates>.
349 =item generate_timestamp()
351 Generate a timestamp from the current time, obeying the
352 'USETIMESTAMPS' config parameter. The Amanda configuration must
355 =item sanitise_filename($fn)
357 "Santitises" a filename by replacing any characters that might have special
358 meaning to a filesystem with underscores. This operation is I<not> reversible,
359 and distinct input filenames I<may> produce identical output filenames.
361 =item unmarshal_tapespec($tapespec)
362 =item marshal_tapespec($filelist)
364 These functions convert between a tapespec -- formerly, and confusingly, called
365 a "tapelist" -- and a perl data structure like
367 [ $label1 => [ $filenum1, $filenum2, .. ],
368 $label2 => [ $filenum1, $filenum2, .. ],
371 Note that a non-tapespec C<$string> will be unmarshalled as C<[ $string, [] ]>.
377 Amanda provides a basic mechanism to lock a file and read its contents. This
378 uses operating-system facilities to acquire an advisory lock, so non-Amanda
379 applications are not prevented from modifying the file while it is locked.
381 To create a lock object, call the C<file_lock> constructor, passing the
384 my $fl = Amanda::Util::file_lock->new($filename)
390 which also reads the contents of the file into memory, accessible via
392 my $state = $fl->data();
394 to change the file contents, call C<write>:
396 $fl->write($new_contents);
398 and unlock the lock with
402 Note that the file will be automatically unlocked if the C<file_lock> object is
405 =head1 Simple File Reading & Writing
407 For reading small files directly into memory with little code
408 overhead, we can use C<slurp>.
410 my $data = slurp $filename;
412 After processing the data, we can write it back to file with C<burp>. This
413 function always completely overwrites the file.
415 burp $filename, $header;
417 These functions can (and should) be exported to the main namespace