2 * Copyright (c) Zmanda, Inc. All Rights Reserved.
4 * This library is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU Lesser General Public License version 2.1
6 * as published by the Free Software Foundation.
8 * This library 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 Lesser General Public
11 * License for more details.
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this library; if not, write to the Free Software Foundation,
15 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
17 * Contact information: Zmanda Inc., 505 N Mathlida Ave, Suite 120
18 * Sunnyvale, CA 94085, USA, or: http://www.zmanda.com
21 %module "Amanda::Util"
22 %include "amglue/amglue.swg"
23 %include "exception.i"
27 /* use a relative path here to avoid conflicting with Perl's util.h. */
28 #include "../common-src/util.h"
33 use Amanda::Debug qw(:init);
35 use POSIX qw(:fcntl_h);
39 Amanda::Util - Runtime support for Amanda applications
41 =head1 Application Initialization
43 Application initialization generally looks like this:
45 use Amanda::Config qw( :init );
46 use Amanda::Util qw( :check_running_as_flags );
49 Amanda::Util::setup_application("myapp", "server", "cmdline");
50 # .. command-line processing ..
51 Amanda::Config::config_init(...);
52 Amanda::Util::finish_setup($RUNNING_AS_DUMPUSER);
56 =item C<setup_application($name, $type, $context)>
58 Set up the operating environment for an application, without requiring any
61 C<$name> is the name of the application, used in log messages, etc. C<$type>
62 is usualy one of "server" or "client". It specifies the subdirectory in which
63 debug logfiles will be created. C<$context> indicates the usual manner in
64 which this application is invoked; one of C<"cmdline"> for a user-invoked
65 command-line utility (e.g., C<amadmin>) which should send human-readable error
66 messages to stderr; C<"daemon"> for a program started by C<amandad>, e.g.,
67 C<sendbackup>; or C<"scriptutil"> for a small program used from shell scripts,
70 Based on C<$type> and C<$context>, this function does the following:
76 sets up debug logging;
80 configures internationalization
88 sets the current working directory to the debug or temporary directory;
92 closes any unnecessary file descriptors as a security meaasure;
96 ignores C<SIGPIPE>; and
100 sets the appropriate target for error messages.
106 # private package variables
111 sub setup_application {
112 my ($name, $type, $context) = @_;
115 croak("no name given") unless ($name);
116 croak("no type given") unless ($type);
117 croak("no context given") unless ($context);
119 # store these as perl values
122 $_pcontext = $context;
124 # and let the C side know about the pname
127 safe_cd(); # (also sets umask)
130 # set up debugging for this application type
134 $SIG{'PIPE'} = 'IGNORE';
136 set_erroutput_type($type, $context);
139 =item C<finish_setup($running_as_flags)>
141 Perform final initialization tasks that require a loaded configuration.
142 Specifically, move the debug log into a configuration-specific
143 subdirectory, and check that the current userid is appropriate for
146 The user is specified by one of the following flags, which are
147 available in export tag C<:check_running_as_flags>:
149 $RUNNING_AS_ROOT # root
150 $RUNNING_AS_DUMPUSER # dumpuser, from configuration
151 $RUNNING_AS_DUMPUSER_PREFERRED # dumpuser, but client_login is OK too
152 $RUNNING_AS_CLIENT_LOGIN # client_login (--with-user at build time)
154 If the flag C<$RUNNING_AS_UID_ONLY> is bit-or'd into C<$running_as_flags>, then
155 the euid is ignored; this is used for programs that expect to be setuid-root.
160 my ($running_as) = @_;
162 my $config_name = Amanda::Config::get_config_name();
165 dbrename($config_name, $_ptype);
168 check_running_as($running_as);
173 Return a "safe" environment hash. For non-setuid programs, this means filtering out any
174 localization variables.
181 delete @rv{qw(IFS CDPATH ENV BASH_ENV LANG)};
183 # delete all LC_* variables
184 for my $var (grep /^LC_/, keys %rv) {
193 amglue_add_flag_tag_fns(running_as_flags);
194 amglue_add_constant(RUNNING_AS_ROOT, running_as_flags);
195 amglue_add_constant(RUNNING_AS_DUMPUSER, running_as_flags);
196 amglue_add_constant(RUNNING_AS_DUMPUSER_PREFERRED, running_as_flags);
197 amglue_add_constant(RUNNING_AS_CLIENT_LOGIN, running_as_flags);
198 amglue_add_constant(RUNNING_AS_UID_ONLY, running_as_flags);
200 /* -------------------------------------------------------------------------
201 * Functions below this line are only meant to be called within this module;
202 * do not call them externally. */
204 void set_pname(char *name);
207 void check_running_as(running_as_flags who);
209 /* Set erroutput_type as appropriate for this process type and context.
211 * @param type: process type
212 * @param context: process context
216 set_erroutput_type(char *type, char *context)
218 if (strcmp(context, "cmdline") == 0) {
219 erroutput_type = ERR_INTERACTIVE;
220 } else if (strcmp(context, "daemon") == 0) {
221 if (strcmp(type, "server") == 0) {
222 erroutput_type = ERR_INTERACTIVE|ERR_AMANDALOG;
223 } else if (strcmp(type, "client") == 0) {
224 erroutput_type = ERR_INTERACTIVE|ERR_SYSLOG;
230 /* Check that fd's 0, 1, and 2 are open, calling critical() if not.
234 fcntl(STDIN, F_GETFD, 0) or critical("Standard input is not open");
235 fcntl(STDOUT, F_GETFD, 0) or critical("Standard output is not open");
236 fcntl(STDERR, F_GETFD, 0) or critical("Standard error is not open");