1#!@PERL@
2#
3# Copyright (c) 2007-2013 Zmanda, Inc.  All Rights Reserved.
4#
5# This program is free software; you can redistribute it and/or
6# modify it under the terms of the GNU General Public License
7# as published by the Free Software Foundation; either version 2
8# of the License, or (at your option) any later version.
9#
10# This program is distributed in the hope that it will be useful, but
11# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12# or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
13# for more details.
14#
15# You should have received a copy of the GNU General Public License along
16# with this program; if not, write to the Free Software Foundation, Inc.,
17# 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
18#
19# Contact information: Zmanda Inc, 465 S. Mathilda Ave., Suite 300
20# Sunnyvale, CA 94086, USA, or: http://www.zmanda.com
21#
22
23use lib '@amperldir@';
24use Getopt::Long;
25use Time::Local;
26use File::Copy;
27use File::Path;
28use Socket;   # for gethostbyname
29use Amanda::Paths;
30use Amanda::Util qw( :constants );
31use Amanda::Constants;
32
33my $confdir="$CONFIG_DIR";
34my $tmpdir="$AMANDA_DBGDIR";
35my $amandahomedir="$localstatedir/lib/amanda";
36my $templatedir="$amdatadir/template.d"; #rpm install template files here
37my $def_tapedev="file:$amandahomedir/vtapes";
38
39my $amanda_user="$Amanda::Constants::CLIENT_LOGIN";
40my $def_config="$Amanda::Constants::DEFAULT_CONFIG";
41my $def_dtimeout="1800";
42my $def_ctimeout="30";
43my $def_etimeout="300";
44my $def_perm=0750;
45my $amanda_conf_perm=0600;
46my $def_tapecycle=10;
47my $config;
48my $vtape_err=0;
49my $holding_err=0;
50my $template_only=0;
51my $parentdir;
52my $host;
53my @pw = getpwuid($<);
54my $dumpuser = $pw[0];
55
56
57#usage
58sub usage {
59        print "$0\n";
60        print "\t\t <config> [--template <template>]\n";
61	print "\t\t[--no-vtape] (do not create virtual tapes)\n";
62        print "\t\t[--tapetype <tapetype>] [--tpchanger <tpchanger>]\n";
63        print "\t\t[--tapedev <tapedev>] [--changerfile <changerfile>]\n";
64        print "\t\t[--changerdev <changerdev>] [--labelstr <labelstr>] \n";
65	print "\t\t[--mailto <mailto>] [--dumpcycle <dumpcycle> (ex: 5days, 1week or 2weeks)]\n";
66	print "\t\t[--runspercycle <runspercycle>] [--runtapes <runtapes>]\n";
67	print "\t\t[--tapecycle <tapecycle>]\n";
68	print "\t\t[--help]\n";
69}
70
71#print and log
72sub mprint {
73    for $fh ( STDOUT, LOG ) {
74	print $fh @_;
75    }
76}
77
78sub log_and_die {
79    my ($err, $cleanup) = @_;
80    print LOG $err;
81    # clean up $config directory if cleanup=1
82    # if error in creating vtape or holding disk,
83    # advise user to create manually, no need to cleanup
84    if ( $cleanup && defined $config  && -e "$confdir/$config" ) {
85	print LOG "cleaning up $confdir/$config\n";
86	if ( -e "$confdir/$config/amanda.conf" ) {
87	    unlink "$confdir/$config/amanda.conf" ||
88	    print LOG "unlink $confdir/$config/amanda.conf failed: $!\n";
89	}
90	if ( -e "$confdir/$config/advanced.conf" ) {
91	    unlink "$confdir/$config/advanced.conf" ||
92	    print LOG "unlink $confdir/$config/advanced.conf failed: $!\n";
93	}
94	if ( -e "$confdir/$config/tapelist" ) {
95	    unlink "$confdir/$config/tapelist" ||
96	    print LOG "unlink $confdir/$config/tapelist failed: $!\n";
97	}
98	if ( -e "$confdir/$config/curinfo" ) {
99	    rmdir "$confdir/$config/curinfo" ||
100	    print LOG "rmdir $confdir/$config failed: $!\n";
101	}
102	if ( -e "$confdir/$config/index" ) {
103	    rmdir "$confdir/$config/index" ||
104	    print LOG "rmdir $confdir/$config/index failed: $!\n";
105	}
106	rmdir "$confdir/$config" ||
107	    print LOG "rmdir $confdir/$config failed: $!\n";
108    }
109    die $err;
110}
111
112
113# rpm installation should have taken care of these. Create one if it's not there
114sub check_gnutarlist_dir {
115    if ( -e "$amandahomedir/gnutar-lists" ) {
116	&mprint ("$amandahomedir/gnutar-lists directory exists\n");
117    }
118    else {
119	mkpath ("$amandahomedir/gnutar-lists", $def_perm) ||
120	    &log_and_die ("ERROR: mkpath:$amandahomedir/gnutar-lists failed: $!\n", 0);
121    }
122}
123
124sub create_conf_dir {
125  unless ( -e "$confdir/$config" ) {
126    mkpath ("$confdir/$config", $def_perm) ||
127      &log_and_die ("ERROR: mkpath: $confdir/$config failed: $!\n", 0);	# $! = system error
128  } else {
129    &log_and_die ("ERROR: Configuration $config exists\n", 0);
130  }
131  unless ( -e "$confdir/template.d" ) {
132    mkpath ("$confdir/template.d", $def_perm)  ||
133      &log_and_die ("ERROR: mkpath: $confdir/template.d failed: $!\n", 0);
134    &mprint ("$confdir/template.d directory created\n");
135  }
136}
137
138sub copy_template_file {
139    my $tplate = $_[0];
140    unless ($tplate) {
141	&log_and_die ("ERROR: template is missing\n", 1);
142    }
143    # create and update amanda.conf
144    open(CONF, "$templatedir/amanda-$tplate.conf")
145	|| &log_and_die ("ERROR: Cannot open $templatedir/amanda-$tplate.conf: $!\n", 1);
146    open(NEWCONF, ">$confdir/$config/amanda.conf") ||
147	&log_and_die ("ERROR: Cannot create $confdir/$config/amanda.conf: $!\n", 1);
148    chmod ($amanda_conf_perm, "$confdir/$config/amanda.conf") ||
149	&log_and_die ("ERROR: Cannot set amanda.conf file access permission: $!\n", 1);
150    while (<CONF>) {
151	$_ =~ s/$def_config/$config/;
152	print NEWCONF $_;
153    }
154    close(CONF);
155    close(NEWCONF);
156    &mprint ("$confdir/$config/amanda.conf created and updated\n");
157}
158
159
160sub create_curinfo_index_dir {
161    mkpath("$confdir/$config/curinfo", $def_perm) ||
162	&log_and_die ("ERROR: mkpath: $confdir/$config/curinfo failed: $!\n", 1);
163    mkpath("$confdir/$config/index", $def_perm) ||
164	&log_and_die ("ERROR: mkpath: $confdir/$config/index failed: $!\n", 1);
165    &mprint ("curinfo and index directory created\n");
166}
167
168sub touch_list_files {
169    open (TLIST, ">$confdir/$config/tapelist")
170	|| &log_and_die ("ERROR: Cannot create tapelist file: $!\n", 1);
171    close (TLIST);
172    &mprint ("tapelist file created\n");
173
174    open (DLIST, ">$confdir/$config/disklist")
175	|| &log_and_die ("ERROR: Cannot create disklist file: $!\n", 1);
176    close (DLIST);
177    &mprint ("disklist file created\n");
178}
179
180# create holding disk directory, check disk space first
181sub create_holding {
182  if ( -d "$amandahomedir/holdings/$config" ) {
183    my $uid = (stat("$amandahomedir/holdings/$config"))[4];
184    my $owner = (getpwuid($uid))[0];
185    unless ( $owner eq $amanda_user ) {
186      &mprint ("WARNING: holding disk directory exists and is not owned by $amanda_user\n");
187      $holding_err++;
188    }
189    return;
190  }
191    my $div=1;
192    my $out = `df -k $amandahomedir`;
193    my @dfout = split(" " , $out);
194    unless ( $#dfout == 12 ) {	# df should output 12 elem
195	&mprint ("WARNING: df failed, holding disk directory not created\n");
196	$holding_err++;
197	return;
198    }
199    unless (( $dfout[1] eq "1K-blocks" ) || ( $dfout[1] eq "kbytes")) {
200         $div=2;	# 512-blocks displayed by df
201     }
202
203    if (( $dfout[10] / $div )  > 1024000 ) { # holding disk is defined 1000 MB
204	&mprint ("creating holding disk directory\n");
205	unless ( -d "$amandahomedir/holdings" ) {
206	mkpath ( "$amandahomedir/holdings", $def_perm) ||
207	    (&mprint ("WARNING: mkpath $amandahomedir/holdings failed: $!\n"), $holding_err++, return );
208    }
209	mkpath ( "$amandahomedir/holdings/$config", $def_perm) ||
210	    (&mprint ("WARNING: mkpath $amandahomedir/holdings/$config failed: $!\n"), $holding_err++, return) ;
211    }
212}
213
214#create default tape dir
215sub create_deftapedir{
216    unless ( -e "$amandahomedir/vtapes" ) {
217	mkpath ( "$amandahomedir/vtapes", $def_perm) ||
218	    ( &mprint ("WARNING: mkpath $amandahomedir/$config/vtapes failed: $!\n"), return );
219    }
220    unless ( -e "$amandahomedir/vtapes/$config" ) {
221	mkpath ( "$amandahomedir/vtapes/$config", $def_perm) ||
222	    ( &mprint ("WARNING: mkpath $amandahomedir/vtapes/$config failed: $!\n"), return );
223    }
224	$parentdir="$amandahomedir/vtapes/$config";
225}
226
227# create and label vtape
228sub create_vtape {
229	&mprint ("creating vtape directory\n");
230	if ($template_only==0){ #  check $template mode
231		$mylabelprefix=$labelstr;   #set labelstr
232		if ($tapedev eq "$def_tapedev/$config"){
233		    &create_deftapedir;
234		}
235		else {
236		    $parentdir=$tapedev;
237		}
238	}
239	else {
240		$mylabelprefix=$config;
241		&create_deftapedir;
242	}
243	unless ( -e $parentdir){
244		&mprint ("WARNING: tapedev $parentdir does not exists, vtapes creation failed!\n");
245		&mprint ("Please create $parentdir and $confdir/$config and rerun the same command or else create vtapes manually.\n");
246		$vtape_err++;
247		return;
248	}
249
250	chdir ("$parentdir") ||
251		( &mprint("WARNING: chdir $parentdir failed: $!\n"), $vtape_err++, return );
252    my $i;
253    &mprint ("amlabel vtapes\n");
254	if (defined $tapecycle) {
255		$tapecycle=~/^\d+/;
256		$tp_cyclelimit=$&;
257
258		# check space
259		my $fsinfo = Amanda::Util::get_fs_usage($parentdir);
260		my $avail_bytes = $fsinfo->{'blocksize'} * $fsinfo->{'bavail'};
261
262		# mysteriously, we need at least 72k per slot, plus 10k overhead.  The
263		# origin of these numbers is unknown.
264		my $needed_bytes = (($tp_cyclelimit*73728)+10240);
265		if ($avail_bytes < $needed_bytes){
266			&mprint ("WARNING: Not enough space for vtapes. Need 72k per slot plus 10k ($needed_bytes bytes); have $avail_bytes available.  Creation of vtapes failed\n");
267			$vtape_err++;
268			return;
269		}
270	}
271	else {
272		$tp_cyclelimit=$def_tapecycle;
273	}
274
275	for $i (1..$tp_cyclelimit) {
276		unless ( -e "slot$i"){
277		    mkpath ("slot$i", $def_perm) ||
278		    ( &mprint ("WARNING: mkpath $parentdir/slot$i failed: $!\n"), $vtape_err++, return);
279		}
280		( @amlabel_out = `$sbindir/amlabel -f $config $mylabelprefix-$i slot $i`) ||
281	        ( &mprint ("WARNING: amlabel vtapes failed at slot $i: $!\n"), $vtape_err++, return);
282    }
283	foreach (@amlabel_out) {
284	  print LOG;
285        }
286	# reset tape to the first slot
287	`$sbindir/amtape $config reset`;
288}
289
290sub create_customconf{
291	   # now create a custom amanda.conf from user input
292	unless ( $mailto )
293	{ $mailto="$amanda_user"; }
294	else {  # untaint mailto which can be evil
295                # reject mailto with the following * ( ) < > [ ] , ; : ! $ \ / "
296	    if ( $mailto =~ /^([^\*\(\)<>\[\]\,\;\:\!\$\\\/\"]+)$/ ) {
297		$mailto = $1;                      #  now untainted
298	    } else {
299		&log_and_die ("ERROR: Invalid data in mailto.\n");  # log this somewhere
300	    }
301	}
302	unless ( $dumpcycle ) { $dumpcycle="1 week"; }
303	unless ( $runspercycle ) { $runspercycle="5"; }
304	unless ( $tapecycle ) { $tapecycle="10 tapes"; }
305	unless ( $runtapes ) { $runtapes="1"; }
306	unless ( $labelstr ) {
307	  if ($template eq "harddisk") {
308	    $labelstr="$config";
309	  } else {
310	    $labelstr="^$config-[0-9][0-9]*\$";
311	  }
312	}
313
314	open (CONF, ">$confdir/$config/amanda.conf") ||
315	    &log_and_die ("ERROR: Cannot create amanda.conf file: $!\n", 1);
316	chmod ($amanda_conf_perm, "$confdir/$config/amanda.conf") ||
317	    &log_and_die ("ERROR: Cannot set amanda.conf file access permission: $!\n", 1);
318
319	print CONF "org \"$config\"\t\t# your organization name for reports\n";
320	print CONF "dumpuser \"$dumpuser\"\t# the user to run dumps under\n";
321	print CONF "mailto \"$mailto\"\t# space separated list of operators at your site\n";
322	print CONF "dumpcycle $dumpcycle\t\t# the number of days in the normal dump cycle\n";
323	print CONF "runspercycle $runspercycle\t\t# the number of amdump runs in dumpcycle days\n";
324	print CONF "tapecycle $tapecycle\t# the number of tapes in rotation\n";
325	print CONF "runtapes $runtapes\t\t# number of tapes to be used in a single run of amdump\n";
326
327	if ((!(defined($template)))||($template eq "harddisk"))
328	  {
329		print CONF "\n";
330		print CONF "define changer my_vtapes {\n";
331		print CONF "    tpchanger \"chg-disk:$tapedev\"\n";
332		print CONF "    property \"num-slot\" \"10\"\n";
333		print CONF "    property \"auto-create-slot\" \"yes\"\n";
334		print CONF "}\n";
335		print CONF "tpchanger \"my_vtapes\"\n\n";
336		unless ( $tapetype ) { $tapetype="HARDDISK"; }
337	  }
338	elsif ($template eq "single-tape")
339	  {
340		print CONF "\n";
341		print CONF "define changer my_single {\n";
342		print CONF "    tpchanger \"chg-single:$tapedev\"\n";
343		print CONF "}\n";
344		print CONF "tpchanger \"my_single\"\n\n";
345		unless ($tapetype) {$tapetype="HP-DAT";}
346	  }
347	elsif ($template eq "tape-changer")
348          {
349		print CONF "\n";
350		print CONF "define changer my_robot {\n";
351		print CONF "    tpchanger \"chg-robot:$changerdev\"\n";
352		print CONF "    property \"tape-device\" \"0=$tapedev\"\n";
353		print CONF "}\n";
354		print CONF "tpchanger \"my_robot\"\n\n";
355		unless ($tapetype)  {$tapetype="HP-DAT";}
356          }
357        else # S3 case
358	  {
359		print CONF "\n";
360		print CONF "define changer my_s3 {\n";
361		print CONF "    tpchanger \"chg-multi:$tapedev\"\n";
362		print CONF "    device-property \"S3_ACCESS_KEY\" \"\"\n";
363		print CONF "    device-property \"S3_SECRET_KEY\" \"\"\n";
364		print CONF "    device-property \"NB_THREADS_BACKUP\" \"\"\n";
365		print CONF "}\n";
366		print CONF "tpchanger \"my_s3\"\n\n";
367	    unless ($tapetype)  {$tapetype="HP-DAT";}
368	  }
369
370	print CONF "tapetype $tapetype\t# what kind of tape it is\n";
371	print CONF "labelstr \"$labelstr\"\t# label constraint regex: all tapes must match\n";
372	print CONF "dtimeout $def_dtimeout\t# number of idle seconds before a dump is aborted\n";
373	print CONF "ctimeout $def_ctimeout\t# max number of secconds amcheck waits for each client\n";
374	print CONF "etimeout $def_etimeout\t# number of seconds per filesystem for estimates\n";
375	print CONF "define dumptype global {\n";
376	print CONF "       comment \"Global definitions\"\n";
377	print CONF "       auth \"bsdtcp\"\n}\n";
378	print CONF "define dumptype gui-base {\n";
379	print CONF "       global\n";
380	print CONF "       program \"GNUTAR\"\n";
381	print CONF "       comment \"gui base dumptype dumped with tar\"\n";
382	print CONF "       compress none\n";
383	print CONF "       index yes\n}\n";
384	if ($tapetype eq "HARDDISK") {
385	  print CONF "define tapetype HARDDISK {\n";
386	  print CONF "       comment \"Virtual Tapes\"\n";
387	  print CONF "       length 5000 mbytes\n}\n";
388	}
389	print CONF "includefile \"advanced.conf\"\n";
390	print CONF "includefile \"$confdir/template.d/dumptypes\"\n";
391	print CONF "includefile \"$confdir/template.d/tapetypes\"\n";
392	close (CONF);
393	mprint ("custom amanda.conf created\n");
394  }
395
396
397sub check_xinetd{
398    &mprint ("/var/lib/amanda/example/xinetd.amandaserver contains the latest Amanda server daemon configuration.\n");
399    &mprint ("Please merge it to /etc/xinetd.d/amandaserver.\n");
400}
401
402
403sub build_amanda_ssh_key{
404  if ( -e "$amandahomedir/.ssh/id_rsa_amdump.pub" ) {
405    if ( -e "$amandahomedir/.ssh/client_authorized_key" ) {
406      &mprint ("$amandahomedir/.ssh/client_authorized_keys exists.\n");
407    }
408    else {
409      open(NEWAUTH, ">$amandahomedir/.ssh/client_authorized_keys") ||
410	(&mprint("WARNING: open $amandahomedir/.ssh/client_authorized_key failed: $!\n"), return);
411      open(PUB, "$amandahomedir/.ssh/id_rsa_amdump.pub") ||
412	(&mprint("WARNING: open $amandahomedir/.ssh/id_rsa_amdump.pub failed: $!\n"), return);
413      print NEWAUTH "from=\"$host\",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,command=\"/usr/lib/amanda/amandad -auth=ssh amdump\" ";
414      while (<PUB>) {
415      print NEWAUTH;
416    }
417      close NEWAUTH;
418      close PUB;
419      &mprint("$amandahomedir/.ssh/client_authorized_keys created. Please append to $amandahomedir/.ssh/authorized_keys file on Amanda clients\n");
420      }
421  }
422}
423
424sub copy_chg_manual_conf {
425  if ( $template eq "single-tape" && !defined $changerfile && !defined $tpchanger)
426    {
427      my $my_changerfile="$confdir/$config/chg-manual.conf";
428      copy("$templatedir/chg-manual.conf", $my_changerfile) ||
429	&mprint ("copy $templatedir/chg-manual.conf to $my_changerfile failed: $!\n");
430    }
431}
432
433#main
434my $ret=0;
435
436$ret = GetOptions ("template=s"=>\$template,
437		   "no-vtape!"=>\$novtape,
438	      "tapetype=s"=>\$tapetype,
439	      "tpchanger=s"=>\$tpchanger,
440	      "tapedev=s"=>\$tapedev,
441	      "changerfile=s"=>\$changerfile,
442	      "changerdev=s"=>\$changerdev,
443	      "labelstr=s"=>\$labelstr,
444	      "mailto=s"=>\$mailto,
445	      "dumpcycle=s"=>\$dumpcycle,
446	      "runspercycle=i"=>\$runspercycle,
447	      "runtapes=i"=>\$runtapes,
448	      "tapecycle=i"=>\$tapecycle,
449	      "help!"=>\$help
450	      );
451
452unless ( $ret ) {
453    &usage;
454    exit 1;
455}
456
457if($help) {
458    &usage;
459    exit 0;
460}
461
462unless ( $#ARGV == 0 ) {
463    print STDERR "ERROR: config name is required.\n";
464    &usage;
465    exit 1;
466}
467else {
468    if ( "$ARGV[0]" =~ /^([-\@\w.]+)$/ ) {
469	$config = $1;                   #  now untainted
470    } else {
471	die ("ERROR: Invalid data in config name.\n");  # log this somewhere
472    }
473}
474
475
476$oldPATH = $ENV{'PATH'};
477
478$ENV{'PATH'} = "/usr/bin:/usr/sbin:/sbin:/bin:/usr/ucb"; # force known path
479delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};
480$date=`date +%Y%m%d%H%M%S`;
481chomp($date);
482my $logfile="$tmpdir/amserverconfig.$date.debug";
483
484Amanda::Util::setup_application("amserverconfig", "server", $CONTEXT_CMDLINE);
485Amanda::Util::finish_setup($RUNNING_AS_ANY);
486
487unless ( -e "$tmpdir" ) {
488    mkpath ("$tmpdir", $def_perm) ||
489	die ("ERROR: mkpath: $tmpdir failed: $!\n");
490}
491
492open (LOG, ">$logfile") || die ("ERROR: Cannot create logfile: $!\n");
493print STDOUT "Logging to $logfile\n";
494
495my $lhost=`hostname`;
496chomp($lhost);
497# get our own canonical name, if possible (we don't sweat the IPv6 stuff here)
498$host=(gethostbyname($lhost))[0];
499
500unless ( $host ) {
501    $host = $lhost;  #gethostbyname() failed, go with hostname output
502}
503
504
505my $need_changer = 0;
506if ( defined $template ) {
507
508    # validate user input to template
509    chomp($template);
510    my $found = 0;
511    @valid_templates = ( "harddisk", "single-tape", "tape-changer", "s3" );
512    foreach $elt (@valid_templates) {
513        if ( $elt eq lc($template) ) {
514            $found = 1;
515            last;
516        }
517    }
518    unless ($found) {
519        print STDERR
520            "valid inputs to --templates are harddisk, single-tape, tape-changer or S3\n";
521        &usage;
522        exit 1;
523    }
524
525    # if tape-changer is chosen, check if mtx is installed
526    if ( $template eq "tape-changer" ) {
527        my $ok = 0;
528        for $dir ( "/usr/sbin", "/usr/local/sbin", "/usr/local/bin",
529            "/usr/bin", "/bin", "/opt/csw/sbin", split( ":", $oldPATH ) )
530        {
531            if ( -e "$dir/mtx" ) {
532                $ok = 1;
533                last;
534            }
535        }
536        unless ($ok) {
537            &mprint(
538                "ERROR: mtx binary not found, tape-changer template will not work and is not installed.\n"
539            );
540            &log_and_die(
541                "ERROR: Please install mtx and rerun the same command.\n",
542                0 );
543        }
544	$need_changer = 1;
545    }
546    elsif ( $template eq "S3" ) {
547	$need_changer = 1;
548    }
549
550}
551
552&create_conf_dir;
553
554if ($need_changer) {
555    unless ($changerfile) {
556	$changerfile = "$confdir/$config/changer.conf";
557    }
558    open( CCONF, ">$changerfile" )
559	|| &log_and_die( "ERROR: Cannot create $changerfile: $!\n", 1 );
560    close(CCONF);
561}
562
563&check_gnutarlist_dir;
564
565# copy dumptypes and tapetypes files if none exists.
566my $dtype="$confdir/template.d/dumptypes";
567my $ttype="$confdir/template.d/tapetypes";
568
569unless ( -e $dtype ) {
570    copy("$templatedir/dumptypes", $dtype ) ||
571    &log_and_die ("ERROR: copy dumptypes failed: $!\n", 1);
572}
573
574
575unless ( -e $ttype ) {
576    copy("$templatedir/tapetypes", $ttype ) ||
577    &log_and_die ("ERROR: copy tapetypes file to $ttype failed: $!\n", 1);
578}
579
580
581
582# update $def_config value to the specified config value in advanced.conf
583    open(ADV, "$templatedir/advanced.conf") || &log_and_die ("ERROR: Cannot open advanced.conf file: $!\n", 1);
584    open(NEWADV, ">$confdir/$config/advanced.conf") ||
585	&log_and_die ("ERROR: Cannot create advanced.conf file: $!\n", 1);
586    while (<ADV>) {
587	$_ =~ s/$def_config/$config/;
588	print NEWADV $_;
589    }
590    close(ADV);
591    close(NEWADV);
592    &mprint ("$confdir/$config/advanced.conf created and updated\n");
593
594
595&create_curinfo_index_dir;
596&touch_list_files;
597
598
599if ( defined $template ) {
600# if any other parameters are provided, create a workable custom config
601	if ( defined $tapetype || defined $tpchanger || defined $tapedev
602	 || defined $changerdev || defined $labelstr || defined $mailto || defined $dumpcycle
603	 || defined $runspercycle || defined $runtapes || defined $tapecycle ) {
604		&mprint("Creating custom configuration using templates\n");
605		create_customconf();
606		if ( $template ne "harddisk" ) {
607		  &create_holding;
608		} else {
609		  if (defined $labelstr) {
610		    if ($labelstr=~/^([-\w.]+)$/) {
611		      &create_vtape unless ( defined $novtape );
612		    } else {
613		      &mprint ("WARNING: Only alphanumeric string is supported in labelstr when using template to create vtapes. ");
614		      &mprint ("If you want to use regex in labelstr, please create vtapes manually.\n");
615		    }
616		  }
617		}
618	      } else {
619		$template_only=1;
620		$tapedev="$def_tapedev/$config";
621		&copy_template_file($template);
622		if ($template ne "harddisk") {
623		  unless ( -e "$amandahomedir/holdings/$config" ) {
624		    &create_holding;
625		  }
626		} else {  # harddisk and template only
627		  unless ( -e "$amandahomedir/vtapes/$config" || defined $novtape ) {
628		    &create_vtape;
629		  }
630		}
631	      }
632	&copy_chg_manual_conf;
633      } else {
634&create_customconf;
635}
636
637&check_xinetd;
638&build_amanda_ssh_key;
639
640if ( $vtape_err ) {
641  &mprint("Error in creating virtual tape, please check log and create virtual tape manually.\n");
642  exit 1;
643}
644
645if ( $holding_err ) {
646  &mprint("Error in creating holding disk, please check log and create holding disk manually.\n");
647  exit 1;
648}
649
650
651
652if ( $vtape_err==0 && $holding_err==0) {
653  &mprint("DONE.\n");
654  exit 0;
655}
656
657
658$ENV{'PATH'} = $oldPATH;
659
660
661# THE END
662Amanda::Util::finish_application();
663